package com.crm.business.crm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.util.JSONObject1O;
import com.crm.business.admin.service.AdminService;
import com.crm.business.crm.mapper.CrmActivityMapper;
import com.crm.business.crm.mapper.CrmInstrumentMapper;
import com.crm.business.crm.service.*;
import com.crm.business.utils.BiTimeUtil;
import com.crm.common.admin.entity.BO.AdminUserBO;
import com.crm.business.utils.AuthUtil;
import com.crm.common.crm.constant.*;
import com.crm.common.crm.entity.BO.CrmSearchParamsBO;
import com.crm.common.crm.entity.PO.BrokenLineDataParameter;
import com.crm.common.crm.entity.PO.CrmActivity;
import com.crm.common.crm.entity.PO.CrmTimeTableData;
import com.crm.common.crm.entity.VO.*;
import com.crm.common.ka.core.common.SystemCodeEnum;
import com.crm.common.ka.core.entity.BasePage;
import com.crm.common.ka.core.entity.UserInfo;
import com.crm.common.ka.core.exception.CrmException;
import com.crm.common.ka.core.feign.admin.entity.*;
import com.crm.common.ka.core.feign.crm.entity.BiAuthority;
import com.crm.common.ka.core.feign.crm.entity.BiParams;
import com.crm.common.crm.entity.BO.CrmSearchBO;
import com.crm.business.servlet.ApplicationContextHolder;
import com.crm.business.utils.UserUtil;
import com.crm.common.utils.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.crm.common.utils.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

import static com.crm.common.crm.constant.CrmEnum.*;


/**
 * <p>
 * 仪表盘 服务实现类
 * </p>
 *
 * @author zhangzhiwei
 * @since 2020-06-04
 */
@Slf4j
@Service
public class CrmInstrumentServiceImpl implements CrmInstrumentService {

    @Autowired
    private CrmInstrumentMapper crmInstrumentMapper;

    @Autowired
    private AdminService adminService;

    @Autowired
    private ICrmActivityService crmActivityService;

    @Autowired
    private ICrmBusinessService crmBusinessService;

    @Autowired
    private CrmActivityMapper crmActivityMapper;

    @Qualifier("adminThreadPoolExecutor")
    @Autowired
    private Executor executor;

    @Override
    public JSONObject queryBulletin(BiParams biParams) {
        BiTimeUtil.BiTimeEntity biTimeEntity = BiTimeUtil.analyzeTime(biParams); //时间
        BiAuthority biAuthority = handleDataType(biParams); //范围
        Map<String, Integer> map = AuthUtil.getDataTypeByUserId();
        Map<String, Object> record = new HashMap<>();
        record.put("businessUserIds", AuthUtil.filterUserIdListByDataType(map.get("business"), biAuthority.getUserIds()));
        record.put("contactsUserIds", AuthUtil.filterUserIdListByDataType(map.get("contacts"), biAuthority.getUserIds()));
        record.put("customerUserIds", AuthUtil.filterUserIdListByDataType(map.get("customer"), biAuthority.getUserIds()));
        record.put("receivablesUserIds", AuthUtil.filterUserIdListByDataType(map.get("receivables"), biAuthority.getUserIds()));
        record.put("contractUserIds", AuthUtil.filterUserIdListByDataType(map.get("contract"), biAuthority.getUserIds()));
        record.put("leadsUserIds", AuthUtil.filterUserIdListByDataType(map.get("leads"), biAuthority.getUserIds()));
        record.put("recordUserIds", AuthUtil.filterUserIdListByDataType(map.get("record"), biAuthority.getUserIds()));
        Map<String, Object> info = crmInstrumentMapper.queryBulletin(biTimeEntity, record);
        boolean isCustom = !StrUtil.isAllEmpty(biParams.getStartTime(), biParams.getEndTime());
        Map<String, Object> prevRecord = new HashMap<>();
        BigDecimal bigDecimal = new BigDecimal("0");
        if (!isCustom) {
            BiTimeUtil.BiTimeEntity timeEntity = BiTimeUtil.prevAnalyzeType(biParams);
            prevRecord = crmInstrumentMapper.queryBulletin(timeEntity, record);
            for (String columnName : info.keySet()) {
                BigDecimal decimal = new BigDecimal(prevRecord.get(columnName).toString());
                BigDecimal newdecimal = new BigDecimal(info.get(columnName).toString());
                if (decimal.equals(bigDecimal) || newdecimal.equals(bigDecimal)) {
                    prevRecord.put(columnName, bigDecimal);
                } else {
                    if (decimal.compareTo(BigDecimal.ZERO) == 0 || newdecimal.compareTo(BigDecimal.ZERO) == 0) {
                        prevRecord.put(columnName, 0);
                    } else {
                        prevRecord.put(columnName, newdecimal.subtract(decimal).divide(decimal, 4, BigDecimal.ROUND_HALF_UP));
                    }
                }
            }
        } else {
            for (String columnName : info.keySet()) {
                prevRecord.put(columnName, bigDecimal);
            }
        }
        return new JSONObject().fluentPut("data", info).fluentPut("prev", prevRecord);

    }

    /**
     * 销售简报的详情
     *
     * @param biInstrumentParams 参数
     * @return data
     */
    @Override
    public BasePage<Map<String, Object>> queryBulletinInfo(BiInstrumentParams biInstrumentParams) {
        BiParams biParams = new BiParams();
        BeanUtils.copyProperties(biInstrumentParams, biParams);

        BiTimeUtil.BiTimeEntity biTimeEntity = BiTimeUtil.analyzeTime(biParams);
        BiAuthority biAuthority = handleDataType(biParams);
        Map<String, Integer> map = AuthUtil.getDataTypeByUserId();
        CrmEnum crmEnum = CrmEnum.parse(biParams.getLabel());
        List<Long> userIds = new ArrayList<>();
        switch (crmEnum) {
            case LEADS:
                userIds = AuthUtil.filterUserIdListByDataType(map.get("leads"), biAuthority.getUserIds());
                break;
            case CUSTOMER:
                userIds = AuthUtil.filterUserIdListByDataType(map.get("customer"), biAuthority.getUserIds());
                break;
            case CONTACTS:
                userIds = AuthUtil.filterUserIdListByDataType(map.get("contacts"), biAuthority.getUserIds());
                break;
            case BUSINESS:
                userIds = AuthUtil.filterUserIdListByDataType(map.get("business"), biAuthority.getUserIds());
                break;
            case CONTRACT:
                userIds = AuthUtil.filterUserIdListByDataType(map.get("contract"), biAuthority.getUserIds());
                break;
            case RECEIVABLES:
                userIds = AuthUtil.filterUserIdListByDataType(map.get("receivables"), biAuthority.getUserIds());
                break;
            default:
                break;
        }
        if (userIds.isEmpty()) {
            return new BasePage<>();
        }
        CrmSearchBO searchBO = new CrmSearchBO();
        searchBO.setPage(biParams.getPage());
        searchBO.setLimit(biParams.getLimit());
        searchBO.setSearch(biParams.getSearch());
        searchBO.setLabel(biParams.getLabel());
        searchBO.setOrder(biParams.getOrder());
        searchBO.setSortField(biParams.getSortField());
        searchBO.setSearchList(biInstrumentParams.getSearchList());
        searchBO.getSearchList().add(new CrmSearchBO.Search("ownerUserId", "text", CrmSearchBO.FieldSearchEnum.IS, userIds.stream().map(Object::toString).collect(Collectors.toList())));
        List<String> dataList = new ArrayList<>();
        dataList.add("涵品");
        searchBO.getSearchList().add(new CrmSearchBO.Search("dataFrom", "text", CrmSearchBO.FieldSearchEnum.IS, dataList));
        if (biParams.getMoneyType() != null) {
            if (biParams.getMoneyType() == 1) {
                searchBO.getSearchList().add(new CrmSearchBO.Search("orderDate", "date", CrmSearchBO.FieldSearchEnum.DATE, Arrays.asList(DateUtil.formatDate(biTimeEntity.getBeginDate()), DateUtil.formatDate(DateUtil.offsetDay(biTimeEntity.getEndDate(), 1)))));
            } else if (biParams.getMoneyType() == 2) {
                searchBO.getSearchList().add(new CrmSearchBO.Search("returnTime", "date", CrmSearchBO.FieldSearchEnum.DATE, Arrays.asList(DateUtil.formatDate(biTimeEntity.getBeginDate()), DateUtil.formatDate(DateUtil.offsetDay(biTimeEntity.getEndDate(), 1)))));
            }
        } else {
            if (!crmEnum.equals(CONTACTS)) {
                if (crmEnum.equals(LEADS)) {
                    String startTime = biInstrumentParams.getStartTime();
                    String endTime = biInstrumentParams.getEndTime();
                    if (!StringUtils.isEmpty(startTime) || !StringUtils.isEmpty(endTime)) {
                        if (DashboardEnum.MARKET.getType().equals(biInstrumentParams.getDashboardType())) {
                            searchBO.getSearchList().add(new CrmSearchBO.Search("leadsCreateTime", "date", CrmSearchBO.FieldSearchEnum.DATE, Arrays.asList(startTime, endTime)));
                        } else if (DashboardEnum.SALES.getType().equals(biInstrumentParams.getDashboardType())) {
                            if(FormType.LEADS.getType().equals(biParams.getFormType())){
                                searchBO.getSearchList().add(new CrmSearchBO.Search("signClassTime", "date", CrmSearchBO.FieldSearchEnum.DATE, Arrays.asList(startTime, endTime)));
                            }else{
                                searchBO.getSearchList().add(new CrmSearchBO.Search("createTime", "date", CrmSearchBO.FieldSearchEnum.DATE, Arrays.asList(startTime, endTime)));
                            }
                        }else{
                            searchBO.getSearchList().add(new CrmSearchBO.Search("leadsCreateTime", "date", CrmSearchBO.FieldSearchEnum.DATE, Arrays.asList(startTime, endTime)));
                        }
                    } else {
                        if (DashboardEnum.MARKET.getType().equals(biInstrumentParams.getDashboardType())) {
                            searchBO.getSearchList().add(new CrmSearchBO.Search("leadsCreateTime", "date", CrmSearchBO.FieldSearchEnum.DATE, Arrays.asList(DateUtil.formatDate(biTimeEntity.getBeginDate()), DateUtil.formatDate(DateUtil.endOfDay(biTimeEntity.getEndDate())))));
                        } else if (DashboardEnum.SALES.getType().equals(biInstrumentParams.getDashboardType())) {
                            if(FormType.LEADS.getType().equals(biParams.getFormType())){
                                searchBO.getSearchList().add(new CrmSearchBO.Search("signClassTime", "date", CrmSearchBO.FieldSearchEnum.DATE, Arrays.asList(DateUtil.formatDateTime(biTimeEntity.getBeginDate()), DateUtil.formatDateTime(DateUtil.endOfDay(biTimeEntity.getEndDate())))));
                            }else{
                                searchBO.getSearchList().add(new CrmSearchBO.Search("createTime", "date", CrmSearchBO.FieldSearchEnum.DATE, Arrays.asList(DateUtil.formatDateTime(biTimeEntity.getBeginDate()), DateUtil.formatDateTime(DateUtil.endOfDay(biTimeEntity.getEndDate())))));
                            }
                        }else{
                            searchBO.getSearchList().add(new CrmSearchBO.Search("leadsCreateTime", "date", CrmSearchBO.FieldSearchEnum.DATE, Arrays.asList(DateUtil.formatDate(biTimeEntity.getBeginDate()), DateUtil.formatDate(DateUtil.endOfDay(biTimeEntity.getEndDate())))));
                        }
                    }

                } else if (crmEnum.equals(CONTRACT)) {
                    String startTime = biInstrumentParams.getStartTime();
                    String endTime = biInstrumentParams.getEndTime();
                    if (!StringUtils.isEmpty(startTime) || !StringUtils.isEmpty(endTime)) {
                        searchBO.getSearchList().add(new CrmSearchBO.Search("createTime", "date", CrmSearchBO.FieldSearchEnum.DATE, Arrays.asList(startTime, endTime)));
                    } else {
                        searchBO.getSearchList().add(new CrmSearchBO.Search("createTime", "date", CrmSearchBO.FieldSearchEnum.DATE_TIME, Arrays.asList(DateUtil.formatDateTime(biTimeEntity.getBeginDate()), DateUtil.formatDateTime(DateUtil.endOfDay(biTimeEntity.getEndDate())))));
                    }
                    List<String> money = new ArrayList<>();
                    money.add("1.00");
                    searchBO.getSearchList().add(new CrmSearchBO.Search("receivedMoney", "floatnumber", CrmSearchBO.FieldSearchEnum.EGT, money));
                } else if (crmEnum.equals(RECEIVABLES)) {
                    String startTime = biInstrumentParams.getStartTime();
                    String endTime = biInstrumentParams.getEndTime();
                    if (!StringUtils.isEmpty(startTime) || !StringUtils.isEmpty(endTime)) {
                        searchBO.getSearchList().add(new CrmSearchBO.Search("returnTime", "date", CrmSearchBO.FieldSearchEnum.DATE, Arrays.asList(DateUtil.formatDate(DateUtil.parse(startTime, DatePattern.NORM_DATETIME_PATTERN)), DateUtil.formatDate(DateUtil.parse(endTime, DatePattern.NORM_DATETIME_PATTERN)))));
                    } else {
                        searchBO.getSearchList().add(new CrmSearchBO.Search("returnTime", "date", CrmSearchBO.FieldSearchEnum.DATE_TIME, Arrays.asList(DateUtil.formatDate(biTimeEntity.getBeginDate()), DateUtil.formatDate(DateUtil.endOfDay(biTimeEntity.getEndDate())))));
                    }

                } else {
                    searchBO.getSearchList().add(new CrmSearchBO.Search("createTime", "date", CrmSearchBO.FieldSearchEnum.DATE_TIME, Arrays.asList(DateUtil.formatDateTime(biTimeEntity.getBeginDate()), DateUtil.formatDateTime(DateUtil.endOfDay(biTimeEntity.getEndDate())))));
                }

            }

        }
        if (biParams.getCheckStatus() != null && biParams.getCheckStatus() == 1) {
            searchBO.getSearchList().add(new CrmSearchBO.Search("checkStatus", "text", CrmSearchBO.FieldSearchEnum.IS, Collections.singletonList("1")));
        }
        if (StringUtils.isNotBlank(biParams.getRepetition())) {
            searchBO.getSearchList().add(new CrmSearchBO.Search("isRepetition", "text", CrmSearchBO.FieldSearchEnum.IS, Collections.singletonList(biParams.getRepetition())));
        }
        if (Optional.ofNullable(biParams.getCategories()).isPresent()) {
            searchBO.getSearchList().add(new CrmSearchBO.Search("categories", "text", CrmSearchBO.FieldSearchEnum.IS, Collections.singletonList(String.valueOf(biParams.getCategories()))));
        }
        if (Optional.ofNullable(biParams.getSalesType()).isPresent()) {
            searchBO.getSearchList().add(new CrmSearchBO.Search("salesType", "text", CrmSearchBO.FieldSearchEnum.IS, Collections.singletonList(String.valueOf(biParams.getSalesType()))));
        }
        if (StringUtils.isNotBlank(biParams.getPeriods())) {
            searchBO.getSearchList().add(new CrmSearchBO.Search("trainingPeriods", "text", CrmSearchBO.FieldSearchEnum.IS, Collections.singletonList(String.valueOf(biParams.getPeriods()))));
        }
        if (crmEnum.equals(CUSTOMER)) {
            searchBO.getSearchList().add(new CrmSearchBO.Search("createUserId", "text", CrmSearchBO.FieldSearchEnum.IS, userIds.stream().map(Object::toString).collect(Collectors.toList())));
        }
        switch (crmEnum) {
            case LEADS:
                return SpringUtils.getBean(ICrmLeadsService.class).queryListByInstrumentImplNotLeads(searchBO);
            case CUSTOMER:
                return SpringUtils.getBean(ICrmCustomerService.class).queryPageList(searchBO);
            case CONTACTS:
                return SpringUtils.getBean(ICrmContactsService.class).queryPageList(searchBO);
            case BUSINESS:
                return SpringUtils.getBean(ICrmBusinessService.class).queryPageList(searchBO);
            case CONTRACT:
                searchBO.getSearchList().add(new CrmSearchBO.Search("checkStatus", "text", CrmSearchBO.FieldSearchEnum.IS, Collections.singletonList("1")));
                return SpringUtils.getBean(ICrmContractService.class).queryPageList(searchBO);
            case RECEIVABLES:
                //查询逻辑改为已通过与审核中的数据 - 20210709
                List<String> list = new ArrayList<>();
                list.add("1");
                list.add("3");
                searchBO.getSearchList().add(new CrmSearchBO.Search("checkStatus", "text", CrmSearchBO.FieldSearchEnum.CONTAINS, list));
//                searchBO.getSearchList().add(new CrmSearchBO.Search("checkStatus", "text", CrmSearchBO.FieldSearchEnum.IS, Collections.singletonList("1")));
                return SpringUtils.getBean(ICrmReceivablesService.class).queryPageList(searchBO);
            default:
                throw new CrmException(SystemCodeEnum.SYSTEM_NO_VALID);
        }
    }

    @Override
    public JSONObject forgottenCustomerCount(BiParams biParams) {
        JSONObject object = new JSONObject();
        Map<String, Integer> map = AuthUtil.getDataTypeByUserId();
        BiAuthority biAuthority = handleDataType(biParams);
        List<Long> userIds = AuthUtil.filterUserIdListByDataType(map.get("customer"), biAuthority.getUserIds());
        Integer sevenDays = crmInstrumentMapper.forgottenCustomerCount(7, userIds);
        Integer fifteenDays = crmInstrumentMapper.forgottenCustomerCount(15, userIds);
        Integer oneMonth = crmInstrumentMapper.forgottenCustomerCount(30, userIds);
        Integer threeMonth = crmInstrumentMapper.forgottenCustomerCount(90, userIds);
        Integer sixMonth = crmInstrumentMapper.forgottenCustomerCount(180, userIds);
        Integer unContactCustomerCount = crmInstrumentMapper.unContactCustomerCount(userIds);
        object.put("sevenDays", sevenDays);
        object.put("fifteenDays", fifteenDays);
        object.put("oneMonth", oneMonth);
        object.put("threeMonth", threeMonth);
        object.put("sixMonth", sixMonth);
        object.put("unContactCustomerCount", unContactCustomerCount);
        return object;
    }

    @Override
    public JSONObject sellFunnel(BiParams biParams) {
        Integer menuId = 103;
        biParams.setMenuId(menuId);
        BiTimeUtil.BiTimeEntity record = BiTimeUtil.analyzeType(biParams);
        List<Long> userIds = record.getUserIds();
        if (userIds.size() == 0) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("list", new ArrayList<>());
            jsonObject.put("sum_money", 0);
            jsonObject.put("sum_shu", 0);
            jsonObject.put("sum_ying", 0);
            return jsonObject;
        }
        Map<String, Object> map = record.toMap();
        map.put("typeId", biParams.getTypeId());
        List<JSONObject> list = crmInstrumentMapper.sellFunnel(map);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("list", list);
        map.put("isEnd", 1);
        List<JSONObject> otherList = crmInstrumentMapper.sellFunnel(map);
        BigDecimal sum_money = new BigDecimal("0");
        BigDecimal sum_shu = new BigDecimal("0");
        BigDecimal sum_ying = new BigDecimal("0");
        for (JSONObject object : otherList) {
            sum_money = sum_money.add(object.getBigDecimal("money"));
            sum_shu = sum_shu.add(object.getBigDecimal("lose"));
            sum_ying = sum_ying.add(object.getBigDecimal("win"));
        }
        ;
        jsonObject.put("sum_money", sum_money);
        jsonObject.put("sum_shu", sum_shu);
        jsonObject.put("sum_ying", sum_ying);
        return jsonObject;
    }

    @Override
    public BasePage<Map<String, Object>> sellFunnelBusinessList(CrmSearchParamsBO crmSearchParamsBO) {
        BiTimeUtil.BiTimeEntity record = BiTimeUtil.analyzeType(crmSearchParamsBO);
        List<Long> userIds = record.getUserIds();
        if (CollUtil.isEmpty(userIds)) {
            return new BasePage<>();
        }
        Map<String, Object> map = record.toMap();
        CrmSearchBO search = new CrmSearchBO();
        search.setPage(crmSearchParamsBO.getPage());
        search.setLimit(crmSearchParamsBO.getLimit());
        search.setLabel(CrmEnum.BUSINESS.getType());
        List<CrmSearchBO.Search> searchList = new ArrayList<>();
        if (StrUtil.isNotEmpty(crmSearchParamsBO.getSearch())) {
            map.put("name", crmSearchParamsBO.getSearch());
        }
        CrmSearchBO.Search entity = crmSearchParamsBO.getEntity();
        map.put("typeId", entity.getValues().get(0));
        map.put("statusId", entity.getValues().get(1));
        List<String> businessIdList = crmInstrumentMapper.sellFunnelBusinessList(map);

        CrmSearchBO.Search entity2 = new CrmSearchBO.Search();
        entity2.setName("businessId");
        entity2.setFormType(FieldEnum.TEXT.getFormType());
        entity2.setSearchEnum(CrmSearchBO.FieldSearchEnum.IS);
        entity2.setValues(businessIdList);
        searchList.add(entity2);

        search.setSearchList(searchList);
        return crmBusinessService.queryPageList(search);
    }

    @Override
    public JSONObject salesTrend(BiParams biParams) {
        BiTimeUtil.BiTimeEntity record = null;
        if (StrUtil.isNotEmpty(biParams.getType())) {
            if ("year".equals(biParams.getType()) || "lastYear".equals(biParams.getType())) {
                biParams.setType(biParams.getType());
                record = BiTimeUtil.analyzeTime(biParams);
            } else {
                String endTime = DateUtil.format(new Date(), "yyyy-MM-dd");
                String startTime = DateUtil.format(DateUtil.offsetMonth(new Date(), -12), "yyyy-MM-dd");
                biParams.setStartTime(startTime);
                biParams.setEndTime(endTime);
            }
        }
        if (StrUtil.isNotEmpty(biParams.getStartTime()) && StrUtil.isNotEmpty(biParams.getEndTime())) {
            Integer startMonth = Integer.valueOf(DateUtil.format(DateUtil.parse(biParams.getStartTime()), "yyyyMM"));
            Integer endMonth = Integer.valueOf(DateUtil.format(DateUtil.parse(biParams.getEndTime()), "yyyyMM"));
            if (endMonth - startMonth < 100) {
                String endTime = DateUtil.format(new Date(), "yyyy-MM-dd");
                String startTime = DateUtil.format(DateUtil.offsetMonth(new Date(), -12), "yyyy-MM-dd");
                biParams.setStartTime(startTime);
                biParams.setEndTime(endTime);
            }
            record = BiTimeUtil.analyzeTime(biParams);
        }
        if (record == null) {
            return new JSONObject().fluentPut("list", new ArrayList<>());
        }
        Integer cycleNum = record.getCycleNum();
        Integer beginTime = record.getBeginTime();
        List<Map<String, Object>> recordList = new ArrayList<>();
        Map<String, Integer> map = AuthUtil.getDataTypeByUserId();
        BiAuthority biAuthority = handleDataType(biParams);
        List<Long> userIds = new ArrayList<>();
        if (Objects.equals(biParams.getLabel(), 1)) {
            userIds.addAll(AuthUtil.filterUserIdListByDataType(map.get("contract"), biAuthority.getUserIds()));
        } else if (Objects.equals(biParams.getLabel(), 2)) {
            userIds.addAll(AuthUtil.filterUserIdListByDataType(map.get("receivables"), biAuthority.getUserIds()));
        }
        for (int i = 1; i <= cycleNum; i++) {
            JSONObject object = new JSONObject();
            object.put("month", MonthEnum.valueOf(DateUtil.parse(beginTime.toString(), record.getDateFormat()).monthStartFromOne()));
            object.put("year", DateUtil.year(DateUtil.parse(beginTime.toString(), record.getDateFormat())));
            object.put("label", biParams.getLabel());
            object.put("userIds", userIds);
            object.put("deptIds", AuthUtil.filterDeptId(biAuthority.getDeptIds()));
            recordList.add(crmInstrumentMapper.salesTrend(record, object));
            beginTime = BiTimeUtil.estimateTime(beginTime);
            record.setBeginTime(beginTime);
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("list", recordList);
        return jsonObject;
    }

    @Override
    public JSONObject queryDataInfo(BiParams biParams) {
        if (BeanUtil.isEmpty(biParams.getDataForm())) {
            biParams.setDataForm("涵品");
        }
        BiAuthority biAuthority = handleDataType(biParams);
        Map<String, Integer> map = AuthUtil.getDataTypeByUserId();
        BiTimeUtil.BiTimeEntity timeEntity = BiTimeUtil.analyzeTime(biParams);
        Map<String, Object> costumer = crmInstrumentMapper.dataInfoCustomer(timeEntity, AuthUtil.filterUserIdListByDataType(map.get("customer"), biAuthority.getUserIds()), biParams.getDataForm());
        Map<String, Object> activity = crmInstrumentMapper.dataInfoActivity(timeEntity, AuthUtil.filterUserIdListByDataType(map.get("customer"), biAuthority.getUserIds()), biParams.getDataForm());
        Map<String, Object> business = crmInstrumentMapper.dataInfoBusiness(timeEntity, AuthUtil.filterUserIdListByDataType(map.get("business"), biAuthority.getUserIds()));
        Map<String, Object> contract = crmInstrumentMapper.dataInfoContract(timeEntity, AuthUtil.filterUserIdListByDataType(map.get("contract"), biAuthority.getUserIds()), biParams.getDataForm());
        Map<String, Object> receivables = crmInstrumentMapper.dataInfoReceivables(timeEntity, AuthUtil.filterUserIdListByDataType(map.get("receivables"), biAuthority.getUserIds()), biParams.getDataForm());
        JSONObject object = new JSONObject();
        object.putAll(costumer);
        object.putAll(activity);
        object.putAll(business);
        object.putAll(contract);
        object.putAll(receivables);
        return object;
    }

    /**
     * 业绩指标
     */
    @Override
    public JSONObject queryPerformance(BiParams biParams) {

        if (BeanUtil.isEmpty(biParams.getDataForm())) {
            biParams.setDataForm("涵品");
        }

        BiTimeUtil.BiTimeEntity record = BiTimeUtil.analyzeTime(biParams);
        Integer cycleNum = record.getCycleNum();
        boolean b = true;
        if (StrUtil.isNotEmpty(biParams.getStartTime()) && StrUtil.isNotEmpty(biParams.getEndTime())) {
            Date start = DateUtil.parseDate(biParams.getStartTime());
            Date end = DateUtil.parseDate(biParams.getEndTime());
            Integer startMonth = Integer.valueOf(DateUtil.format(start, "yyyyMM"));
            Integer endMonth = Integer.valueOf(DateUtil.format(end, "yyyyMM"));
            b = !startMonth.equals(endMonth);
            if (start.getTime() == DateUtil.beginOfMonth(start).getTime() && end.getTime() == DateUtil.beginOfDay(DateUtil.endOfMonth(start)).getTime()) {
                String sqlDateFormat = "%Y%m";
                String dateFormat = "yyyyMM";
                Integer beginTime = Integer.valueOf(DateUtil.format(start, dateFormat));
                Integer finalTime = Integer.valueOf(DateUtil.format(end, dateFormat));
                record.setCycleNum(1).setBeginTime(beginTime).setFinalTime(finalTime).setSqlDateFormat(sqlDateFormat).setDateFormat(dateFormat);
                b = true;
            }
        }

        Integer beginTime = record.getBeginTime();
        Integer status = biParams.getLabel();
        String type = biParams.getType();
        if ("month".equals(type) || "lastMonth".equals(type)) {
            cycleNum = 1;
        }
        List<String> mouthList = new ArrayList<>();
        for (int i = 1; i <= cycleNum; i++) {
            String month = MonthEnum.valueOf(DateUtil.parse(beginTime.toString(), record.getDateFormat()).monthStartFromOne());
            mouthList.add(month);
            beginTime = BiTimeUtil.estimateTime(beginTime);
        }
        JSONObject kv = new JSONObject(record.toMap()).fluentPut("label", status);
        Map<String, Integer> map = AuthUtil.getDataTypeByUserId();
        BiAuthority biAuthority = handleDataType(biParams);
        if (ObjectUtil.equal(status, 1)) {
            kv.put("userIds", AuthUtil.filterUserIdListByDataType(map.get("contract"), biAuthority.getUserIds()));
        } else if (ObjectUtil.equal(status, 2)) {
            kv.put("userIds", AuthUtil.filterUserIdListByDataType(map.get("receivables"), biAuthority.getUserIds()));
        }
        if ("week".equals(type) || "lastWeek".equals(type) || "today".equals(type) || "yesterday".equals(type)) {
            b = false;
        }
        kv.put("deptIds", biAuthority.getDeptIds());
        kv.put("monthList", mouthList);
        kv.put("year", DateUtil.year(DateUtil.parse(record.getBeginTime().toString(), record.getDateFormat())));
        kv.put("queryItem", b);
        kv.put("dataFrom", biParams.getDataForm());
        JSONObject dataRecord = crmInstrumentMapper.queryPerformance(kv);
        BigDecimal achievementMoneys = dataRecord.getBigDecimal("achievementMoneys");
        if (achievementMoneys != null) {
            if (achievementMoneys.compareTo(BigDecimal.ZERO) == 0) {
                dataRecord.put("proportion", new BigDecimal("100"));
            } else {
                BigDecimal bigDecimal = dataRecord.getBigDecimal("money").divide(achievementMoneys, 4, BigDecimal.ROUND_HALF_UP);
                bigDecimal = bigDecimal.multiply(new BigDecimal("100"));
                dataRecord.put("proportion", bigDecimal);
            }
        }

        if(status == 2){
            //回款金额需减去退款等金额
            BigDecimal refundMoney = crmInstrumentMapper.queryPerformanceRefundMoney(kv);
            BigDecimal money = (BigDecimal) dataRecord.get("money");
            money = money.subtract(refundMoney);

            BigDecimal overdueMoney = crmInstrumentMapper.queryPerformanceOverdueMoney(kv);
            money = money.subtract(overdueMoney);
            dataRecord.put("money", money);
        }

        dataRecord.put(1 == status ? "contractMoneys" : "receivablesMoneys", dataRecord.get("money"));
        return dataRecord;
    }

    @Override
    public BasePage<CrmActivity> queryRecordList(BiParams biParams) {
        Long userId = biParams.getUserId();
        Integer deptId = biParams.getDeptId();
        String startTime = biParams.getStartTime();
        String endTime = biParams.getEndTime();
        Integer dataType = biParams.getDataType();
        Integer crmType = biParams.getLabel();
        Integer queryType = biParams.getQueryType();
        Integer subUser = biParams.getSubUser();
        String search = biParams.getSearch() == null ? null : biParams.getSearch().trim();
        BiAuthority biAuthority = handleDataType(biParams);
        List<Long> userIds = biAuthority.getUserIds();
        if (CollUtil.isEmpty(userIds)) {
            return new BasePage<>();
        }
        if (subUser != null) {
            if (subUser == 1 && ObjectUtil.isAllEmpty(userId, deptId)) {
                userIds = adminService.queryChildUserId(UserUtil.getUserId());
            } else if (subUser == 0) {
                userIds = Collections.singletonList(UserUtil.getUserId());
            }
        }
        if (UserUtil.isAdmin() && ObjectUtil.isAllEmpty(userId, deptId) && subUser == null && dataType == null) {
            userIds = adminService.queryUserList();
        }
        Integer type = BiTimeUtil.analyzeType(biParams.getType());
        if (!UserUtil.isAdmin()) {
            Integer followRecordReadMenuId = adminService.queryMenuId("crm", "followRecord", "read");
            List<Long> authUserIdList = AuthUtil.getUserIdByAuth(followRecordReadMenuId);
            if (authUserIdList.size() == 0) {
                throw new CrmException(SystemCodeEnum.SYSTEM_NO_AUTH);
            }
        }
        Map<String, Integer> map = AuthUtil.getDataTypeByUserId();
        CrmEnum crmEnum = CrmEnum.parse(crmType);
        if (crmEnum != null) {
            switch (crmEnum) {
                case CUSTOMER:
                    AuthUtil.filterUserIdListByDataType(map.get("customer"), userIds);
                    break;
                case CONTACTS:
                    AuthUtil.filterUserIdListByDataType(map.get("contacts"), userIds);
                    break;
                case BUSINESS:
                    AuthUtil.filterUserIdListByDataType(map.get("business"), userIds);
                    break;
                case CONTRACT:
                    AuthUtil.filterUserIdListByDataType(map.get("contract"), userIds);
                    break;
                case RECEIVABLES:
                    AuthUtil.filterUserIdListByDataType(map.get("receivables"), userIds);
                    break;
                default:
                    break;
            }
        }
        BasePage<CrmActivity> page = crmActivityMapper.queryRecordList(biParams.parse(), Dict.create().set("crmType", crmType).set("type", type).set("userIds", userIds).set("startTime", startTime)
                .set("endTime", endTime).set("queryType", queryType).set("search", search));
        for (CrmActivity crmActivity : page.getList()) {
            SimpleUser data = adminService.queryUserById(crmActivity.getCreateUserId());
            crmActivity.setUserImg(data.getImg());
            crmActivity.setRealname(data.getRealname());
            crmActivityService.buildActivityRelation(crmActivity);
        }
        return page;
    }

    @Override
    public List<JSONObject> queryRecordCount(BiParams biParams) {
        BiAuthority biAuthority = handleDataType(biParams);
        List<Long> userIds = biAuthority.getUserIds();
        if (CollUtil.isEmpty(userIds)) {
            return new ArrayList<>();
        }
        //1.今天 2.昨天 3.本周 4.上周 5.本月6.上月7.本季度8.上季度9.本年10上年
        Integer type = BiTimeUtil.analyzeType(biParams.getType());
        Dict kv = Dict.create().set("type", type).set("startTime", biParams.getStartTime()).set("endTime", biParams.getEndTime());
        Map<String, Integer> map = AuthUtil.getDataTypeByUserId();
        kv.set("businessUserIds", AuthUtil.filterUserIdListByDataType(map.get("business"), userIds));
        kv.set("contactsUserIds", AuthUtil.filterUserIdListByDataType(map.get("contacts"), userIds));
        kv.set("customerUserIds", AuthUtil.filterUserIdListByDataType(map.get("customer"), userIds));
        kv.set("receivablesUserIds", AuthUtil.filterUserIdListByDataType(map.get("receivables"), userIds));
        kv.set("contractUserIds", AuthUtil.filterUserIdListByDataType(map.get("contract"), userIds));
        kv.set("leadsUserIds", AuthUtil.filterUserIdListByDataType(map.get("leads"), userIds));
        kv.set("recordUserIds", AuthUtil.filterUserIdListByDataType(map.get("record"), userIds));
        List<JSONObject> recordList = crmInstrumentMapper.queryRecordCount(kv);
        if (recordList.stream().noneMatch(record -> LEADS.getType().equals(record.getInteger("crmType")))) {
            recordList.add(new JSONObject().fluentPut("crmType", LEADS.getType()).fluentPut("count", 0));
        }
        if (recordList.stream().noneMatch(record -> CrmEnum.CUSTOMER.getType().equals(record.getInteger("crmType")))) {
            recordList.add(new JSONObject().fluentPut("crmType", CrmEnum.CUSTOMER.getType()).fluentPut("count", 0));
        }
        if (recordList.stream().noneMatch(record -> CONTACTS.getType().equals(record.getInteger("crmType")))) {
            recordList.add(new JSONObject().fluentPut("crmType", CONTACTS.getType()).fluentPut("count", 0));
        }
        if (recordList.stream().noneMatch(record -> CrmEnum.BUSINESS.getType().equals(record.getInteger("crmType")))) {
            recordList.add(new JSONObject().fluentPut("crmType", CrmEnum.BUSINESS.getType()).fluentPut("count", 0));
        }
        if (recordList.stream().noneMatch(record -> CONTRACT.getType().equals(record.getInteger("crmType")))) {
            recordList.add(new JSONObject().fluentPut("crmType", CONTRACT.getType()).fluentPut("count", 0));
        }
        return recordList;
    }

    private BiAuthority handleDataType(BiParams biParams) {
        //数据类型
        DataTypeEnum typeEnum = DataTypeEnum.parse(biParams.getDataType());
        Integer[] deptIdArray = biParams.getDeptIdArray();
        Long[] userArray = biParams.getUserArray();
        List<Long> userIdList = new ArrayList<>();
        List<Integer> deptIdList = new ArrayList<>();
        if (typeEnum != null) {
            if (typeEnum == DataTypeEnum.SELF) {
                userIdList.add(UserUtil.getUserId());
            } else if (typeEnum == DataTypeEnum.SELF_AND_CHILD) {
                userIdList.addAll(adminService.queryChildUserId(UserUtil.getUserId()));
                userIdList.add(UserUtil.getUserId());
            } else if (typeEnum == DataTypeEnum.DEPT) {
                deptIdList.add(UserUtil.getUser().getDeptId());
                userIdList.addAll(adminService.queryUserByDeptIds(deptIdList));
            } else if (typeEnum == DataTypeEnum.DEPT_AND_CHILD) {
                deptIdList.addAll(adminService.queryChildDeptId(UserUtil.getUser().getDeptId()));
                deptIdList.add(UserUtil.getUser().getDeptId());
                userIdList.addAll(adminService.queryUserByDeptIds(deptIdList));
            } else if (typeEnum == DataTypeEnum.CHANNEL_SALES) {
                userIdList.addAll(adminService.queryChannelSales());
            } else if (typeEnum == DataTypeEnum.DEPT_SELECT) {
                //当为部门选择器的时候
                List<Integer> deptlist = Arrays.asList(deptIdArray);
                userIdList.addAll(adminService.queryUserByDeptIds(deptlist));
            }
            else if (typeEnum == DataTypeEnum.USER_SELECT) {
                //当为人员选择器的时候
                List<Long> userArrayList = Arrays.asList(userArray);
                userIdList.addAll(userArrayList);
            }
            else {
//                userIdList.addAll(adminService.queryUserList().getData());
//                deptIdList.addAll(adminService.queryChildDeptId(0).getData());
                if (UserUtil.isAdmin()) {
                    userIdList.addAll(adminService.queryUserList());
                } else {
                    userIdList.addAll(adminService.queryChildUserId(UserUtil.getUserId()));
                    userIdList.add(UserUtil.getUserId());
                }
            }
        } else {
            if (1 == biParams.getIsUser()) {
                if (null == biParams.getDeptId()) {
                    if (biParams.getUserId() == null) {
                        if (UserUtil.isAdmin()) {
                            userIdList.addAll(adminService.queryUserList());
                        } else {
                            userIdList.addAll(adminService.queryChildUserId(UserUtil.getUserId()));
                            userIdList.add(UserUtil.getUserId());
                        }
                    } else {
                        if (UserUtil.isAdmin()) {
                            userIdList.add(biParams.getUserId());
                        } else {
                            UserInfo userInfo = adminService.queryLoginUserInfo(biParams.getUserId());
                            boolean isAdmin = userInfo.getUserId().equals(UserUtil.getSuperUser()) || Optional.ofNullable(userInfo.getRoles()).orElse(new ArrayList<>()).contains(userInfo.getSuperRoleId());
                            if (!isAdmin) {
                                userIdList.add(biParams.getUserId());
                            }
                        }
                    }
                } else {
                    AdminUserBO adminUserBO = new AdminUserBO();
                    adminUserBO.setDeptId(biParams.getDeptId());
                    BasePage<AdminUserEntityVO> basePageResult = SpringUtils.getBean(AdminService.class).queryUserList(adminUserBO);
                    List<AdminUserEntityVO> list = basePageResult.getList();
                    userIdList = new ArrayList<>();
                    for (AdminUserEntityVO adminUserVO : list) {
                        userIdList.add(adminUserVO.getUserId());
                    }
                    List<Integer> queryChildDeptId = SpringUtils.getBean(AdminService.class).queryChildDeptId(biParams.getDeptId());
                    deptIdList = queryChildDeptId;
                }
            } else if (0 == biParams.getIsUser() && biParams.getDeptId() != null) {
                List<Integer> data = adminService.queryChildDeptId(biParams.getDeptId());
                data.add(biParams.getDeptId());
                deptIdList.addAll(data);
                userIdList.addAll(adminService.queryUserByDeptIds(deptIdList));
            }
        }
        BiAuthority authority = new BiAuthority();
        authority.setUserIds(userIdList);
        authority.setDeptIds(deptIdList);
        return authority;
    }

    @Autowired
    private ICrmCustomerService crmCustomerService;

    @Override
    public BasePage<Map<String, Object>> forgottenCustomerPageList(BiParams biParams) {
        BiAuthority biAuthority = handleDataType(biParams);
        List<Long> userIds = biAuthority.getUserIds();
        if (CollUtil.isEmpty(userIds)) {
            return new BasePage<>();
        }
        Integer day = biParams.getDay();
        Map<String, Integer> map = AuthUtil.getDataTypeByUserId();
        AuthUtil.filterUserIdListByDataType(map.get("customer"), userIds);
        List<Integer> customerIds = crmCustomerService.forgottenCustomer(day, userIds, biParams.getSearch());
        if (customerIds.size() == 0) {
            return new BasePage<>();
        }
        CrmSearchBO searchBO = new CrmSearchBO();
        searchBO.setPage(biParams.getPage());
        searchBO.setLimit(biParams.getLimit());
        searchBO.setLabel(CrmEnum.CUSTOMER.getType());
        List<String> collect = customerIds.stream().map(Object::toString).collect(Collectors.toList());
        searchBO.setSearchList(Collections.singletonList(new CrmSearchBO.Search("_id", "id", CrmSearchBO.FieldSearchEnum.ID, collect)));
        return crmCustomerService.queryPageList(searchBO);
    }

    @Override
    public BasePage<Map<String, Object>> unContactCustomerPageList(BiParams biParams) {
        BiAuthority biAuthority = handleDataType(biParams);
        List<Long> userIds = biAuthority.getUserIds();
        if (CollUtil.isEmpty(userIds)) {
            return new BasePage<>();
        }
        String search = biParams.getSearch();
        Map<String, Integer> map = AuthUtil.getDataTypeByUserId();
        AuthUtil.filterUserIdListByDataType(map.get("customer"), userIds);
        List<Integer> customerIds = crmCustomerService.unContactCustomer(search, userIds);
        if (customerIds.size() == 0) {
            return new BasePage<>();
        }
        CrmSearchBO searchBO = new CrmSearchBO();
        searchBO.setPage(biParams.getPage());
        searchBO.setLimit(biParams.getLimit());
        searchBO.setLabel(CrmEnum.CUSTOMER.getType());
        List<String> collect = customerIds.stream().map(Object::toString).collect(Collectors.toList());
        searchBO.setSearchList(Collections.singletonList(new CrmSearchBO.Search("_id", "id", CrmSearchBO.FieldSearchEnum.ID, collect)));
        return crmCustomerService.queryPageList(searchBO);
    }

    /**
     * 仪表盘的数据
     *
     * @param biParams
     * @return
     * @throws Exception
     */
    @Override
    public DashBoardVO querySalesData(BiParams biParams) throws Exception {

        DashBoardVO dashBoardVO = new DashBoardVO();

        //查询时间的范围
        BiTimeUtil.BiTimeEntity biTimeEntity = BiTimeUtil.analyzeTime(biParams);
        //环比时间范围
        BiTimeUtil.BiTimeEntity momTimeRangeEntity = CrmInstrumentServiceImpl.moM(biParams.getType(), biParams.getStartTime(),
                biParams.getEndTime());
        //当前用户可查询对象，用来区分查询范围
        BiAuthority biAuthority = handleDataType(biParams);

        //限制范围内的客户总数
        Integer customerCount = crmInstrumentMapper.queryCustomerCount(biAuthority.getUserIds(), biTimeEntity);
        //限制范围内的线索总数
        Integer leadsCount = crmInstrumentMapper.queryLeadsCount(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams);
        //限制范围内的联系人总数
        Integer contactsCount = crmInstrumentMapper.queryContactsCount(biAuthority.getUserIds(), biTimeEntity);

        //当前线索数
        CompletableFuture<Void> customer = CompletableFuture.runAsync(() -> {
            DashBoardVO.CustomerData customerData = this.getCustomerData(biTimeEntity, momTimeRangeEntity,
                    biAuthority, leadsCount, biParams.getDataForm());
            dashBoardVO.setCustomerData(customerData);
        }, executor);

        //客服加微信数
        CompletableFuture<Void> addWechat = CompletableFuture.runAsync(() -> {
            DashBoardVO.AddWechatData addWechatData = this.getAddWechatData(biTimeEntity, momTimeRangeEntity,
                    biAuthority, leadsCount, biParams.getDataForm());
            dashBoardVO.setAddWechatData(addWechatData);
        }, executor);

        //客户报课数
        CompletableFuture<Void> customerApply = CompletableFuture.runAsync(() -> {
            DashBoardVO.CustomerApplyData customerApplyData = this.getCustomerApplyData(biTimeEntity,
                    momTimeRangeEntity, biAuthority, leadsCount, biParams.getDataForm());
            dashBoardVO.setCustomerApplyData(customerApplyData);
        }, executor);

        //销售加微信数
        CompletableFuture<Void> salesAddWechat = customerApply.thenRunAsync(() -> {
            DashBoardVO.SalesAddWechatData salesAddWechatData = this.getSalesAddWechatData(biTimeEntity,
                    momTimeRangeEntity, biAuthority, dashBoardVO.getCustomerApplyData().getData(), biParams.getDataForm());
            dashBoardVO.setSalesAddWechatData(salesAddWechatData);
        }, executor);

        /*CompletableFuture<Void> salesAddWechat = CompletableFuture.runAsync(() -> {
            DashBoardVO.SalesAddWechatData salesAddWechatData = this.getSalesAddWechatData(biTimeEntity,
                    momTimeRangeEntity, biAuthority, customerCount);
            dashBoardVO.setSalesAddWechatData(salesAddWechatData);
        }, executor);*/

        //进群客户数
        CompletableFuture<Void> customerJoinGroup = CompletableFuture.runAsync(() -> {
            DashBoardVO.CustomerJoinGroupData customerJoinGroupData = this.getCustomerJoinGroupData(biTimeEntity,
                    momTimeRangeEntity, biAuthority, customerCount, biParams.getDataForm());
            dashBoardVO.setCustomerJoinGroupData(customerJoinGroupData);
        }, executor);

        //销售客户成交数
        CompletableFuture<Void> dealSuccessful = CompletableFuture.runAsync(() -> {
            DashBoardVO.DealSuccessfulData dealSuccessfulData = this.getDealSuccessfulData(biTimeEntity,
                    momTimeRangeEntity, biAuthority, customerCount, biParams.getDataForm());
            dashBoardVO.setDealSuccessfulData(dealSuccessfulData);
        }, executor);

        //线索成交数(除以线索数据)
        CompletableFuture<Void> dealSuccessfulLeads = CompletableFuture.runAsync(() -> {
            DashBoardVO.DealSuccessfulLeads dealSuccessfulData = this.queryDealSuccessfulLeads(biTimeEntity,
                    momTimeRangeEntity, biAuthority, leadsCount, biParams.getDataForm());
            dashBoardVO.setDealSuccessfulLeads(dealSuccessfulData);
        }, executor);

        //VIP课程复购率
        CompletableFuture<Void> repurchase = CompletableFuture.runAsync(() -> {
            DashBoardVO.RepurchaseData repurchaseData = this.getRepurchaseData(biTimeEntity,
                    momTimeRangeEntity, biAuthority, contactsCount, biParams.getDataForm());
            dashBoardVO.setRepurchaseData(repurchaseData);
        }, executor);

        //转介绍
        CompletableFuture<Void> transferIntroduction = CompletableFuture.runAsync(() -> {
            DashBoardVO.TransferIntroductionData transferIntroductionData = this.getTransferIntroductionData(biTimeEntity,
                    momTimeRangeEntity, biAuthority, contactsCount, biParams.getDataForm());
            dashBoardVO.setTransferIntroductionData(transferIntroductionData);
        }, executor);

        //合同金额
        CompletableFuture<Void> contractAmount = CompletableFuture.runAsync(() -> {
            DashBoardVO.ContractAmountData contractAmountData = this.getContractAmountData(biTimeEntity,
                    momTimeRangeEntity, biAuthority, biParams.getDataForm());
            dashBoardVO.setContractAmountData(contractAmountData);
        }, executor);

        //回款金额
        CompletableFuture<Void> payBack = CompletableFuture.runAsync(() -> {
            DashBoardVO.PayBackData payBackData = this.getPayBackData(biTimeEntity,
                    momTimeRangeEntity, biAuthority, biParams.getDataForm());
            dashBoardVO.setPayBackData(payBackData);
        }, executor);

        //定稿成交率
        CompletableFuture<Void> finalizedDealRate = CompletableFuture.runAsync(() -> {
            DashBoardVO.FinalizedDealRateData finalizedDealRateData = new DashBoardVO.FinalizedDealRateData();
            finalizedDealRateData.setData(0);
            finalizedDealRateData.setRate("0.00%");
            finalizedDealRateData.setMom("0.00%");
            dashBoardVO.setFinalizedDealRateData(finalizedDealRateData);
        }, executor);

        CompletableFuture.allOf(customer, addWechat, customerApply, salesAddWechat, customerJoinGroup, dealSuccessful,
                repurchase, transferIntroduction, contractAmount, payBack, finalizedDealRate, dealSuccessfulLeads
        ).exceptionally((e) -> {
            e.printStackTrace();
            return null;
        }).join();

        return dashBoardVO;
    }

    /**
     * 回款金额
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public DashBoardVO.PayBackData getPayBackData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                  BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                  BiAuthority biAuthority, String dataFrom) {

        BigDecimal payBackAmount = crmInstrumentMapper.queryPayBackAmount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            BigDecimal payBackAmountMom = crmInstrumentMapper.queryPayBackAmount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity);
            mom = calculateMom(payBackAmount, payBackAmountMom);
        }

        //应回款金额
        BigDecimal payed = crmInstrumentMapper.queryPayedBackAmount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String rate = this.calculateRate(payBackAmount, payed);

        DashBoardVO.PayBackData payBackData = new DashBoardVO.PayBackData();
        payBackData.setData(payBackAmount);
        payBackData.setMom(mom);
        payBackData.setRate(rate);

        return payBackData;
    }

    /**
     * 合同金额
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public DashBoardVO.ContractAmountData getContractAmountData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                BiAuthority biAuthority, String dataFrom) {

        BigDecimal contractAmount = crmInstrumentMapper.queryContractAmount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            BigDecimal contractAmountMom = crmInstrumentMapper.queryContractAmount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity);
            mom = calculateMom(contractAmount, contractAmountMom);
        }

        //实付金额
        BigDecimal payed = crmInstrumentMapper.queryContractPayed(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String rate = this.calculateRate(contractAmount, payed);

        DashBoardVO.ContractAmountData contractAmountData = new DashBoardVO.ContractAmountData();
        contractAmountData.setData(contractAmount);
        contractAmountData.setMom(mom);
        contractAmountData.setRate(rate);

        return contractAmountData;
    }

    /**
     * 转介绍
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public DashBoardVO.TransferIntroductionData getTransferIntroductionData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                            BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                            BiAuthority biAuthority,
                                                                            Integer contactsCount, String dataFrom) {

        Integer transferIntroductionCount = crmInstrumentMapper.queryTransferIntroductionCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            Integer transferIntroductionCountMom = crmInstrumentMapper.queryTransferIntroductionCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity);
            mom = calculateMom(transferIntroductionCount, transferIntroductionCountMom);
        }

        String rate = this.calculateRate(transferIntroductionCount, contactsCount);

        DashBoardVO.TransferIntroductionData transferIntroductionData = new DashBoardVO.TransferIntroductionData();
        transferIntroductionData.setData(transferIntroductionCount);
        transferIntroductionData.setMom(mom);
        transferIntroductionData.setRate(rate);

        return transferIntroductionData;
    }

    /**
     * VIP课程复购率
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public DashBoardVO.RepurchaseData getRepurchaseData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                        BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                        BiAuthority biAuthority,
                                                        Integer contactsCount, String dataFrom) {

        Integer repurchaseCount = crmInstrumentMapper.queryRepurchaseCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            Integer repurchaseCountMom = crmInstrumentMapper.queryRepurchaseCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity);
            mom = calculateMom(repurchaseCount, repurchaseCountMom);
        }

        String rate = this.calculateRate(repurchaseCount, contactsCount);

        DashBoardVO.RepurchaseData repurchaseData = new DashBoardVO.RepurchaseData();
        repurchaseData.setData(repurchaseCount);
        repurchaseData.setMom(mom);
        repurchaseData.setRate(rate);

        return repurchaseData;
    }

    /**
     * 销售客户成交数 - 20210521修改逻辑：有效合同数/全部客户数 queryCustomerNumByData
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public DashBoardVO.DealSuccessfulData getDealSuccessfulData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                BiAuthority biAuthority,
                                                                Integer customerCount, String dataFrom) {

        Integer dealSuccessfulCount = crmInstrumentMapper.queryDealSuccessfulCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        //求出有效合同数
        Integer contractCount = crmInstrumentMapper.queryContractCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            Integer contractCountMom = crmInstrumentMapper.queryContractCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity);
            mom = calculateMom(contractCount, contractCountMom);
        }

        String rate = this.calculateRate(contractCount, customerCount);

        DashBoardVO.DealSuccessfulData dealSuccessfulData = new DashBoardVO.DealSuccessfulData();
        dealSuccessfulData.setData(dealSuccessfulCount);
        dealSuccessfulData.setMom(mom);
        dealSuccessfulData.setRate(rate);

        return dealSuccessfulData;
    }

    /**
     * 线索总数、线索成交率，环比上月 queryCustomerNumByData
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public DashBoardVO.DealSuccessfulLeads queryDealSuccessfulLeads(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                    BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                    BiAuthority biAuthority,
                                                                    Integer leadsCount, String dataFrom) {

        //求出有效合同数
        Integer contractCount = crmInstrumentMapper.queryContractCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            Integer contractCountMom = crmInstrumentMapper.queryContractCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity);
            mom = calculateMom(contractCount, contractCountMom);
        }

        //计算转化率
        String rate = this.calculateRate(contractCount, leadsCount);

        DashBoardVO.DealSuccessfulLeads dealSuccessfulLeads = new DashBoardVO.DealSuccessfulLeads();
        dealSuccessfulLeads.setData(leadsCount);
        dealSuccessfulLeads.setMom(mom);
        dealSuccessfulLeads.setRate(rate);

        return dealSuccessfulLeads;
    }


    /**
     * 进群客户数
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public DashBoardVO.CustomerJoinGroupData getCustomerJoinGroupData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                      BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                      BiAuthority biAuthority,
                                                                      Integer customerCount, String dataFrom) {

        Integer customerJoinGroupCount = crmInstrumentMapper.queryCustomerJoinGroupCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            Integer customerJoinGroupCountMom = crmInstrumentMapper.queryCustomerJoinGroupCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity);
            mom = calculateMom(customerJoinGroupCount, customerJoinGroupCountMom);
        }

        String rate = this.calculateRate(customerJoinGroupCount, customerCount);

        DashBoardVO.CustomerJoinGroupData customerJoinGroupData = new DashBoardVO.CustomerJoinGroupData();
        customerJoinGroupData.setData(customerJoinGroupCount);
        customerJoinGroupData.setMom(mom);
        customerJoinGroupData.setRate(rate);

        return customerJoinGroupData;
    }

    /**
     * 销售加微信数
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public DashBoardVO.SalesAddWechatData getSalesAddWechatData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                BiAuthority biAuthority,
                                                                Integer customerCount, String dataFrom) {

        Integer salesAddWechatCount = crmInstrumentMapper.querySalesAddWechatCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            Integer salesAddWechatCountMom = crmInstrumentMapper.querySalesAddWechatCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity);
            mom = calculateMom(salesAddWechatCount, salesAddWechatCountMom);
        }

        String rate = this.calculateRate(salesAddWechatCount, customerCount);

        DashBoardVO.SalesAddWechatData salesAddWechatData = new DashBoardVO.SalesAddWechatData();
        salesAddWechatData.setData(salesAddWechatCount);
        salesAddWechatData.setMom(mom);
        salesAddWechatData.setRate(rate);

        return salesAddWechatData;
    }

    /**
     * 查询客户报课数
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public DashBoardVO.CustomerApplyData getCustomerApplyData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                              BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                              BiAuthority biAuthority,
                                                              Integer leadsCount, String dataFrom) {

        Integer customerApplyCount = crmInstrumentMapper.queryCustomerApplyCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity, new BiParams());

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            Integer customerApplyCountMom = crmInstrumentMapper.queryCustomerApplyCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity, new BiParams());
            mom = calculateMom(customerApplyCount, customerApplyCountMom);
        }

        String rate = this.calculateRate(customerApplyCount, leadsCount);

        DashBoardVO.CustomerApplyData customerApplyData = new DashBoardVO.CustomerApplyData();
        customerApplyData.setData(customerApplyCount);
        customerApplyData.setMom(mom);
        customerApplyData.setRate(rate);

        return customerApplyData;
    }

    public MarketingDepartmentDashBoardVO.CustomerApplyData getMarketingDepartmentCustomerApplyData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                                                    BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                                                    BiAuthority biAuthority,
                                                                                                    Integer leadsCount, Integer leadsCountNoCf, Integer leadsCountCf, String dataFrom, BiParams biParams, BiParams biParams_nocf, BiParams biParams_cf) {

        Integer customerApplyCount = crmInstrumentMapper.queryCustomerApplyCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity, biParams);

        Integer customerApplyCount_NoCf = crmInstrumentMapper.queryCustomerApplyCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity, biParams_nocf);

        Integer customerApplyCount_Cf = crmInstrumentMapper.queryCustomerApplyCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity, biParams_cf);

        String mom = "时间范围为全部时，没有环比";
        String mom2 = "时间范围为全部时，没有环比";
        String mom3 = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            Integer customerApplyCountMom = crmInstrumentMapper.queryCustomerApplyCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity, biParams);
            mom = calculateMom(customerApplyCount, customerApplyCountMom);

            Integer customerApplyCountMom_NoCf = crmInstrumentMapper.queryCustomerApplyCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity, biParams_nocf);
            mom2 = calculateMom(customerApplyCount_NoCf, customerApplyCountMom_NoCf);

            Integer customerApplyCountMom_Cf = crmInstrumentMapper.queryCustomerApplyCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity, biParams_cf);
            mom3 = calculateMom(customerApplyCount_Cf, customerApplyCountMom_Cf);
        }

        String rate = this.calculateRate(customerApplyCount, leadsCount);
        String rate2 = this.calculateRate(customerApplyCount_NoCf, leadsCountNoCf);
        String rate3 = this.calculateRate(customerApplyCount_Cf, leadsCountCf);
        MarketingDepartmentDashBoardVO.CustomerApplyData customerApplyData = new MarketingDepartmentDashBoardVO.CustomerApplyData();
        customerApplyData.setData(customerApplyCount);
        customerApplyData.setData2(customerApplyCount_NoCf);
        customerApplyData.setData3(customerApplyCount_Cf);
        if (mom.indexOf("%") != -1) {
            customerApplyData.setMom(Double.valueOf(mom.split("%")[0]));
        } else {
            customerApplyData.setMom(0);
        }
        if (mom2.indexOf("%") != -1) {
            customerApplyData.setMom2(Double.valueOf(mom2.split("%")[0]));
        } else {
            customerApplyData.setMom2(0);
        }
        if (mom3.indexOf("%") != -1) {
            customerApplyData.setMom3(Double.valueOf(mom3.split("%")[0]));
        } else {
            customerApplyData.setMom3(0);
        }
        customerApplyData.setRate(rate);
        customerApplyData.setRate2(rate2);
        customerApplyData.setRate3(rate3);
        customerApplyData.setLabel("客户报课数");
        customerApplyData.setTitle("客户报课数");
        customerApplyData.setType("leads");
        customerApplyData.setPlaTip("leadsTip");
        customerApplyData.setLabelValue(1);

        return customerApplyData;
    }

    /**
     * 查询客服添加微信数
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public DashBoardVO.AddWechatData getAddWechatData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                      BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                      BiAuthority biAuthority,
                                                      Integer leadsCount, String dataFrom) {

        Integer addWechatCount = crmInstrumentMapper.queryAddWechatCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity, new BiParams());

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            Integer customerCountMom = crmInstrumentMapper.queryAddWechatCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity, new BiParams());
            mom = calculateMom(addWechatCount, customerCountMom);
        }

        String rate = this.calculateRate(addWechatCount, leadsCount);

        DashBoardVO.AddWechatData addWechatData = new DashBoardVO.AddWechatData();
        addWechatData.setData(addWechatCount);
        addWechatData.setMom(mom);
        addWechatData.setRate(rate);

        return addWechatData;
    }

    public MarketingDepartmentDashBoardVO.AddWechatData getMarketingDepartmentAddWechatData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                                            BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                                            BiAuthority biAuthority,
                                                                                            Integer leadsCount, Integer leadsCountNoCf, Integer leadsCountCf, String dataFrom, BiParams biParams, BiParams biParams_nocf, BiParams biParams_cf) {

        Integer addWechatCount = crmInstrumentMapper.queryAddWechatCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity, biParams);


        Integer addWechatCount_NoCf = crmInstrumentMapper.queryAddWechatCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity, biParams_nocf);

        Integer addWechatCount_Cf = crmInstrumentMapper.queryAddWechatCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity, biParams_cf);

        String mom = "时间范围为全部时，没有环比";
        String mom2 = "时间范围为全部时，没有环比";
        String mom3 = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            Integer customerCountMom = crmInstrumentMapper.queryAddWechatCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity, biParams);
            mom = calculateMom(addWechatCount, customerCountMom);


            Integer customerCountMom_NoCf = crmInstrumentMapper.queryAddWechatCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity, biParams_nocf);
            mom2 = calculateMom(addWechatCount_NoCf, customerCountMom_NoCf);


            Integer customerCountMom2_Cf = crmInstrumentMapper.queryAddWechatCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity, biParams_cf);
            mom3 = calculateMom(addWechatCount_Cf, customerCountMom2_Cf);
        }

        String rate = this.calculateRate(addWechatCount, leadsCount);
        String rate2 = this.calculateRate(addWechatCount_NoCf, leadsCountNoCf);
        String rate3 = this.calculateRate(addWechatCount_Cf, leadsCountCf);
        MarketingDepartmentDashBoardVO.AddWechatData addWechatData = new MarketingDepartmentDashBoardVO.AddWechatData();
        addWechatData.setData(addWechatCount);
        addWechatData.setData2(addWechatCount_NoCf);
        addWechatData.setData3(addWechatCount_Cf);
        if (mom.indexOf("%") != -1) {
            addWechatData.setMom(Double.valueOf(mom.split("%")[0]));
        } else {
            addWechatData.setMom(0);
        }
        if (mom2.indexOf("%") != -1) {
            addWechatData.setMom2(Double.valueOf(mom2.split("%")[0]));
        } else {
            addWechatData.setMom2(0);
        }
        if (mom3.indexOf("%") != -1) {
            addWechatData.setMom3(Double.valueOf(mom3.split("%")[0]));
        } else {
            addWechatData.setMom3(0);
        }

        addWechatData.setRate(rate);
        addWechatData.setRate2(rate2);
        addWechatData.setRate3(rate3);
        addWechatData.setLabel("客服添加微信数");
        addWechatData.setTitle("客服添加微信数");
        addWechatData.setType("leads");
        addWechatData.setPlaTip("leadsTip");
        addWechatData.setLabelValue(1);
        return addWechatData;
    }

    /**
     * 查询客户数
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public DashBoardVO.CustomerData getCustomerData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                    BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                    BiAuthority biAuthority,
                                                    Integer leadsCount, String dataFrom) {
        //SELECT COUNT(*) FROM bill_crm_customer customer WHERE `status` != 3 AND owner_user_id IN (?) AND DATE_FORMAT(customer.create_time,?) BETWEEN ? AND ?;

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            Integer leadsCountMom = crmInstrumentMapper.queryLeadsCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity, new BiParams());
            //计算环比百分比
            mom = this.calculateMom(leadsCount, leadsCountMom);
        }

        Integer leadsCountForConverted = crmInstrumentMapper.queryLeadsCountForConverted(dataFrom, biAuthority.getUserIds(), timeRangeEntity, new BiParams());
        Integer leadsCountForNotConverted = crmInstrumentMapper.queryLeadsCountForNotConverted(dataFrom, biAuthority.getUserIds(), timeRangeEntity, new BiParams());

        DashBoardVO.CustomerData customerData = new DashBoardVO.CustomerData();
        customerData.setData(leadsCount);
        customerData.setMom(mom);
        customerData.setConverted(leadsCountForConverted == null ? 0 : leadsCountForConverted);
        customerData.setNotConverted(leadsCountForNotConverted == null ? 0 : leadsCountForNotConverted);

        return customerData;
    }

    public MarketingDepartmentDashBoardVO.CustomerData getMarketingDepartmentCustomerData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                                          BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                                          BiAuthority biAuthority,
                                                                                          Integer leadsCount, Integer leadsCountNoCf, Integer leadsCountCf, String dataFrom, BiParams biParams, BiParams biParams_nocf, BiParams biParams_cf) {
        //SELECT COUNT(*) FROM bill_crm_customer customer WHERE `status` != 3 AND owner_user_id IN (?) AND DATE_FORMAT(customer.create_time,?) BETWEEN ? AND ?;

//        String mom = "时间范围为全部时，没有环比";
//        if (!timeRangeEntity.getIsSelectAll()) {
//            Integer leadsCountMom = crmInstrumentMapper.queryLeadsCount(dataFrom,biAuthority.getUserIds(), momTimeRangeEntity,new BiParams());
//            //计算环比百分比
//            mom = this.calculateMom(leadsCount, leadsCountMom);
//        }


        //转化为客户
        Integer leadsCountForConverted = crmInstrumentMapper.queryLeadsCountForConverted(dataFrom, biAuthority.getUserIds(), timeRangeEntity, biParams);
        //未转化表单数量
        Integer leadsCountForNotConverted = crmInstrumentMapper.queryLeadsCountForNotConverted(dataFrom, biAuthority.getUserIds(), timeRangeEntity, biParams);

        //转化为客户 不重复
        Integer leadsCountForConverted_notcf = crmInstrumentMapper.queryLeadsCountForConverted(dataFrom, biAuthority.getUserIds(), timeRangeEntity, biParams_nocf);
        //未转化表单数量 不重复

        Integer leadsCountForNotConverted_notcf = crmInstrumentMapper.queryLeadsCountForNotConverted(dataFrom, biAuthority.getUserIds(), timeRangeEntity, biParams_nocf);
        //转化为客户  重复
        Integer leadsCountForConverted_cf = crmInstrumentMapper.queryLeadsCountForConverted(dataFrom, biAuthority.getUserIds(), timeRangeEntity, biParams_cf);
        //未转化表单数量 重复
        Integer leadsCountForNotConverted_cf = crmInstrumentMapper.queryLeadsCountForNotConverted(dataFrom, biAuthority.getUserIds(), timeRangeEntity, biParams_cf);
        MarketingDepartmentDashBoardVO.CustomerData customerData = new MarketingDepartmentDashBoardVO.CustomerData();
        customerData.setData(leadsCount);
//        customerData.setMom(mom);
        customerData.setConverted(leadsCountForConverted == null ? 0 : leadsCountForConverted);
        customerData.setNotConverted(leadsCountForNotConverted == null ? 0 : leadsCountForNotConverted);

        //不重复
        customerData.setData2(leadsCountNoCf);
        customerData.setConverted2(leadsCountForConverted_notcf == null ? 0 : leadsCountForConverted_notcf);
        customerData.setNotConverted2(leadsCountForNotConverted_notcf == null ? 0 : leadsCountForNotConverted_notcf);
        //重复
        customerData.setData3(leadsCountCf);
        customerData.setConverted3(leadsCountForConverted_cf == null ? 0 : leadsCountForConverted_cf);
        customerData.setNotConverted3(leadsCountForNotConverted_cf == null ? 0 : leadsCountForNotConverted_cf);


        customerData.setLabel("获取表单数量");
        customerData.setTitle("获取表单数量");
        customerData.setType("leads");
        customerData.setPlaTip("leadsTip");
        customerData.setLabelValue(1);

        return customerData;
    }


    /**
     * 计算转化率
     *
     * @param count      有效的数量
     * @param totalCount 总数
     * @return 转化率字符串
     */
    private String calculateRate(Integer count, Integer totalCount) {

        BigDecimal valid = new BigDecimal(count.toString());
        BigDecimal total = new BigDecimal(totalCount.toString());

        BigDecimal rate;
        if (totalCount == 0) {
            rate = valid.divide(new BigDecimal("1"), 2, RoundingMode.HALF_UP);
        } else {
            rate = valid.divide(total, 4, RoundingMode.HALF_UP);
        }

        return rate.multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP) + "%";
    }

    /**
     * 计算转化率
     *
     * @param count      有效的数量
     * @param totalCount 总数
     * @return 转化率字符串
     */
    private String calculateRate(BigDecimal count, BigDecimal totalCount) {

        BigDecimal rate;
        if (totalCount.compareTo(new BigDecimal("0")) == 0) {
            rate = count.divide(new BigDecimal("1"), 2, RoundingMode.HALF_UP);
        } else {
            rate = count.divide(totalCount, 4, RoundingMode.HALF_UP);
        }

        return rate.multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP) + "%";
    }

    /**
     * 计算环比百分比
     *
     * @param count    当前期数值
     * @param countMom 上期期数值
     * @return mom
     */
    private String calculateMom(Integer count, Integer countMom) {
        BigDecimal mom;
        BigDecimal current = new BigDecimal(count.toString());
        BigDecimal last = new BigDecimal(countMom.toString());
        if (last.compareTo(new BigDecimal("0")) == 0) {
            mom = current.divide(new BigDecimal("1"), 4, RoundingMode.HALF_UP);
        } else {
            mom = current.subtract(last).divide(last, 4, RoundingMode.HALF_UP);
        }
        return mom.multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP) + "%";
    }

    /**
     * 计算环比百分比
     *
     * @param count    当前期数值
     * @param countMom 上期期数值
     * @return mom
     */
    private String calculateMom(BigDecimal count, BigDecimal countMom) {
        BigDecimal mom;
        if (countMom.compareTo(new BigDecimal("0")) == 0) {
            mom = count.divide(new BigDecimal("1"), 4, RoundingMode.HALF_UP);
        } else {
            mom = count.subtract(countMom).divide(countMom, 4, RoundingMode.HALF_UP);
        }
        return mom.multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP) + "%";
    }

    /**
     * 获取环比时间
     *
     * @param type
     * @param startTime
     * @param endTime
     * @return
     * @throws Exception
     */
    public static BiTimeUtil.BiTimeEntity moM(String type, String startTime, String endTime) throws Exception {

        Date beginDate = DateUtil.date();
        Date endDate = DateUtil.date();
        int cycleNum = 12;
        String sqlDateFormat = "%Y%m";
        String dateFormat = "yyyyMM";

        if (!StringUtils.isEmpty(type)) {

            switch (type) {
                case "today":
                    beginDate = DateUtil.offsetDay(DateUtil.date(), -1);
                    endDate = DateUtil.offsetDay(DateUtil.date(), -1);
                    sqlDateFormat = "%Y%m%d";
                    dateFormat = "yyyyMMdd";
                    cycleNum = 1;
                    break;
                case "yesterday":
                    beginDate = DateUtil.offsetDay(DateUtil.date(), -2);
                    endDate = DateUtil.offsetDay(DateUtil.date(), -2);
                    sqlDateFormat = "%Y%m%d";
                    dateFormat = "yyyyMMdd";
                    cycleNum = 1;
                    break;
                case "week":
                    beginDate = DateUtil.beginOfWeek(DateUtil.offsetWeek(DateUtil.date(), -1));
                    endDate = DateUtil.endOfWeek(DateUtil.offsetWeek(DateUtil.date(), -1));
                    sqlDateFormat = "%Y%m%d";
                    dateFormat = "yyyyMMdd";
                    cycleNum = 7;
                    break;
                case "lastWeek":
                    beginDate = DateUtil.beginOfWeek(DateUtil.offsetWeek(DateUtil.date(), -2));
                    endDate = DateUtil.endOfWeek(DateUtil.offsetWeek(DateUtil.date(), -2));
                    sqlDateFormat = "%Y%m%d";
                    dateFormat = "yyyyMMdd";
                    cycleNum = 7;
                    break;
                case "month":
                    beginDate = DateUtil.beginOfMonth(DateUtil.offsetMonth(DateUtil.date(), -1));
                    endDate = DateUtil.endOfMonth(DateUtil.offsetMonth(DateUtil.date(), -1));
                    sqlDateFormat = "%Y%m%d";
                    dateFormat = "yyyyMMdd";
                    cycleNum = (int) DateUtil.between(beginDate, endDate, DateUnit.DAY) + 1;
                    break;
                case "lastMonth":
                    beginDate = DateUtil.beginOfMonth(DateUtil.offsetMonth(DateUtil.date(), -2));
                    endDate = DateUtil.endOfMonth(DateUtil.offsetMonth(DateUtil.date(), -2));
                    sqlDateFormat = "%Y%m%d";
                    dateFormat = "yyyyMMdd";
                    cycleNum = (int) DateUtil.between(beginDate, endDate, DateUnit.DAY) + 1;
                    break;
                case "quarter":
                    beginDate = DateUtil.beginOfQuarter(DateUtil.offsetMonth(DateUtil.date(), -3));
                    endDate = DateUtil.endOfQuarter(DateUtil.offsetMonth(DateUtil.date(), -3));
                    cycleNum = 3;
                    break;
                case "lastQuarter":
                    beginDate = DateUtil.beginOfQuarter(DateUtil.offsetMonth(DateUtil.date(), -6));
                    endDate = DateUtil.endOfQuarter(DateUtil.offsetMonth(DateUtil.date(), -6));
                    cycleNum = 3;
                    break;
                case "year":
                    beginDate = DateUtil.beginOfYear(DateUtil.offsetMonth(DateUtil.date(), -12));
                    endDate = DateUtil.endOfYear(DateUtil.offsetMonth(DateUtil.date(), -12));
                    break;
                case "lastYear":
                    beginDate = DateUtil.beginOfYear(DateUtil.offsetMonth(DateUtil.date(), -24));
                    endDate = DateUtil.endOfYear(DateUtil.offsetMonth(DateUtil.date(), -24));
                    break;
            }
        } else {
            if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) {
                throw new Exception("没有选择时间范围，也没有输入自定义时间范围！");
            }

            Date start;
            Date end;
            if (startTime.length() == 6) {
                start = DateUtil.parse(startTime, "yyyyMM");
                end = DateUtil.endOfMonth(DateUtil.parse(endTime, "yyyyMM"));
            } else {
                start = DateUtil.parse(startTime);
                end = DateUtil.parse(endTime);
            }
            Integer startMonth = Integer.valueOf(DateUtil.format(start, "yyyyMM"));
            Integer endMonth = Integer.valueOf(DateUtil.format(end, "yyyyMM"));
            if (startMonth.equals(endMonth)) {
                sqlDateFormat = "%Y%m%d";
                dateFormat = "yyyyMMdd";
                Long diffDay = DateUtil.between(start, end, DateUnit.DAY);
                cycleNum = diffDay.intValue() + 1;
            } else {
                sqlDateFormat = "%Y%m";
                dateFormat = "yyyyMM";
                int diffYear = Integer.valueOf(endMonth.toString().substring(0, 4)) - Integer.valueOf(startMonth.toString().substring(0, 4));
                int diffMonth = endMonth % 100 - startMonth % 100 + 1;
                cycleNum = diffYear * 12 + diffMonth;
            }

            //自定义时间的上个周期
            beginDate = DateUtil.offsetDay(start, -1 * cycleNum);
            endDate = DateUtil.offsetDay(end, -1 * cycleNum);
        }

        Integer beginTime = Integer.valueOf(DateUtil.format(beginDate, dateFormat));
        Integer finalTime = Integer.valueOf(DateUtil.format(endDate, dateFormat));
        return new BiTimeUtil.BiTimeEntity(sqlDateFormat, dateFormat, beginDate, endDate, cycleNum, beginTime, finalTime, new ArrayList<>());
    }

    /**
     * 获取时间
     *
     * @param timeRange
     * @param startTime
     * @param endTime
     * @return
     * @throws Exception
     */
    public static TimeRangeEntity timeRange(Integer timeRange, String startTime, String endTime) throws Exception {

        Date beginDate = DateUtil.date();
        Date endDate = DateUtil.date();
        int cycleNum = 12;
        String sqlDateFormat = "%Y%m";
        String dateFormat = "yyyyMM";
        boolean isSelectAll = false;

        if (timeRange != null) {
            TimeRangeEnum timeRangeEnum = TimeRangeEnum.getEnum(timeRange);

            if (timeRangeEnum == null)
                throw new Exception("时间处理失败");

            switch (timeRangeEnum) {
                case ALL:
                    isSelectAll = true;
                    break;
                case TODAY:
                    beginDate = DateUtil.beginOfDay(DateUtil.date());
                    endDate = DateUtil.endOfDay(DateUtil.date());
                    sqlDateFormat = "%Y%m%d";
                    dateFormat = "yyyyMMdd";
                    cycleNum = 1;
                    break;
                case YESTERDAY:
                    beginDate = DateUtil.offsetDay(DateUtil.date(), -1);
                    endDate = DateUtil.offsetDay(DateUtil.date(), -1);
                    sqlDateFormat = "%Y%m%d";
                    dateFormat = "yyyyMMdd";
                    cycleNum = 1;
                    break;
                case WEEK:
                    beginDate = DateUtil.beginOfWeek(DateUtil.date());
                    endDate = DateUtil.endOfWeek(DateUtil.date());
                    sqlDateFormat = "%Y%m%d";
                    dateFormat = "yyyyMMdd";
                    cycleNum = 7;
                    break;
                case LAST_WEEK:
                    beginDate = DateUtil.beginOfWeek(DateUtil.offsetWeek(DateUtil.date(), -1));
                    endDate = DateUtil.endOfWeek(DateUtil.offsetWeek(DateUtil.date(), -1));
                    sqlDateFormat = "%Y%m%d";
                    dateFormat = "yyyyMMdd";
                    cycleNum = 7;
                    break;
                case MONTH:
                    beginDate = DateUtil.beginOfMonth(DateUtil.date());
                    endDate = DateUtil.endOfMonth(DateUtil.date());
                    sqlDateFormat = "%Y%m%d";
                    dateFormat = "yyyyMMdd";
                    cycleNum = (int) DateUtil.between(beginDate, endDate, DateUnit.DAY) + 1;
                    break;
                case LAST_MONTH:
                    beginDate = DateUtil.beginOfMonth(DateUtil.offsetMonth(DateUtil.date(), -1));
                    endDate = DateUtil.endOfMonth(DateUtil.offsetMonth(DateUtil.date(), -1));
                    sqlDateFormat = "%Y%m%d";
                    dateFormat = "yyyyMMdd";
                    cycleNum = (int) DateUtil.between(beginDate, endDate, DateUnit.DAY) + 1;
                    break;
                case QUARTERLY:
                    beginDate = DateUtil.beginOfQuarter(DateUtil.date());
                    endDate = DateUtil.endOfQuarter(DateUtil.date());
                    cycleNum = 3;
                    break;
                case LAST_QUARTERLY:
                    beginDate = DateUtil.beginOfQuarter(DateUtil.offsetMonth(DateUtil.date(), -3));
                    endDate = DateUtil.endOfQuarter(DateUtil.offsetMonth(DateUtil.date(), -3));
                    cycleNum = 3;
                    break;
                case YEAR:
                    beginDate = DateUtil.beginOfYear(DateUtil.date());
                    endDate = DateUtil.endOfYear(DateUtil.date());
                    break;
                case LAST_YEAR:
                    beginDate = DateUtil.beginOfYear(DateUtil.offsetMonth(DateUtil.date(), -12));
                    endDate = DateUtil.endOfYear(DateUtil.offsetMonth(DateUtil.date(), -12));
                    break;
            }
        } else {
            if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) {
                throw new Exception("没有选择时间范围，也没有输入自定义时间范围！");
            }

            Date start;
            Date end;
            if (startTime.length() == 6) {
                start = DateUtil.parse(startTime, "yyyyMM");
                end = DateUtil.endOfMonth(DateUtil.parse(endTime, "yyyyMM"));
            } else {
                start = DateUtil.parse(startTime);
                end = DateUtil.parse(endTime);
            }
            Integer startMonth = Integer.valueOf(DateUtil.format(start, "yyyyMM"));
            Integer endMonth = Integer.valueOf(DateUtil.format(end, "yyyyMM"));
            if (startMonth.equals(endMonth)) {
                sqlDateFormat = "%Y%m%d";
                dateFormat = "yyyyMMdd";
                Long diffDay = DateUtil.between(start, end, DateUnit.DAY);
                cycleNum = diffDay.intValue() + 1;
            } else {
                sqlDateFormat = "%Y%m";
                dateFormat = "yyyyMM";
                int diffYear = Integer.valueOf(endMonth.toString().substring(0, 4)) - Integer.valueOf(startMonth.toString().substring(0, 4));
                int diffMonth = endMonth % 100 - startMonth % 100 + 1;
                cycleNum = diffYear * 12 + diffMonth;
            }
            beginDate = start;
            endDate = end;
        }

        Integer beginTime = Integer.valueOf(DateUtil.format(beginDate, dateFormat));
        Integer finalTime = Integer.valueOf(DateUtil.format(endDate, dateFormat));
        return new TimeRangeEntity(isSelectAll, sqlDateFormat, dateFormat, beginDate, endDate, cycleNum,
                beginTime, finalTime);
    }

    /**
     * 查询员工范围
     *
     * @param staffRange
     * @return
     */
    public static BiAuthority staffRange(Integer staffRange) {
        //转为查询范围枚举
        StaffRangeEnum staffRangeEnum = StaffRangeEnum.parse(staffRange);

        List<Long> userIdList = new ArrayList<>();
        List<Integer> deptIdList = new ArrayList<>();

        if (staffRangeEnum != null) {
            AdminService adminService = SpringUtils.getBean(AdminService.class);
            if (staffRangeEnum == StaffRangeEnum.ALL) {
                userIdList.addAll(adminService.queryUserList());
            } else if (staffRangeEnum == StaffRangeEnum.DEPT) {
                deptIdList.add(UserUtil.getUser().getDeptId());
                userIdList.addAll(adminService.queryUserByDeptIds(deptIdList));
            } else if (staffRangeEnum == StaffRangeEnum.DEPT_AND_CHILD_DEPT) {
                deptIdList.addAll(adminService.queryChildDeptId(UserUtil.getUser().getDeptId()));
                deptIdList.add(UserUtil.getUser().getDeptId());
                userIdList.addAll(adminService.queryUserByDeptIds(deptIdList));
            } else if (staffRangeEnum == StaffRangeEnum.SELF) {
                userIdList.add(UserUtil.getUserId());
            } else if (staffRangeEnum == StaffRangeEnum.CHILD_DEPT) {
                deptIdList.addAll(adminService.queryChildDeptId(UserUtil.getUser().getDeptId()));
                userIdList.addAll(adminService.queryUserByDeptIds(deptIdList));
            } else if (staffRangeEnum == StaffRangeEnum.CHANNEL_SALES) {
                //todo 渠道销售情况
            }
        }

        BiAuthority authority = new BiAuthority();
        authority.setUserIds(userIdList);
        authority.setDeptIds(deptIdList);
        return authority;
    }

    @Override
    public JSONObject queryStatisticsCurve(BrokenLineDataParameter brokenLineDataParameter) {
//        dataForm
        if (StringUtils.isEmpty(brokenLineDataParameter.getDataFrom())) {
            brokenLineDataParameter.setDataFrom("涵品");
        }

        List<Long> userIdList = new ArrayList<>();
        if (brokenLineDataParameter.getDeptId() == null) {
            if (UserUtil.isAdmin()) {
                userIdList.addAll(adminService.queryUserList());
            } else {
                userIdList.addAll(adminService.queryChildUserId(UserUtil.getUserId()));
                userIdList.add(UserUtil.getUserId());
            }
        } else {
            AdminUserBO adminUserBO = new AdminUserBO();
            adminUserBO.setDeptId(brokenLineDataParameter.getDeptId());
            BasePage<AdminUserEntityVO> basePageResult = SpringUtils.getBean(AdminService.class).queryUserList(adminUserBO);
            List<AdminUserEntityVO> list = basePageResult.getList();
            for (AdminUserEntityVO adminUserVO : list) {
                userIdList.add(adminUserVO.getUserId());
            }
        }


        //设置查询条件：开始时间、结束时间
        String queryStartDate = null;
        String queryEndDate = null;
        if (StringUtils.isNotEmpty(brokenLineDataParameter.getYear())) {
            queryStartDate = brokenLineDataParameter.getYear() + "-01-01 00:00:00";
            queryEndDate = brokenLineDataParameter.getYear() + "-12-31 23:59:59";
        } else {
            Calendar c = Calendar.getInstance();
            //过去一年
            c.setTime(new Date());
            c.add(Calendar.YEAR, -1);
            Date y = c.getTime();
            queryStartDate = DateUtil.format(y, "yyyy-MM-dd") + " 00:00:00";
            queryEndDate = DateUtil.format(DateUtil.date(), "yyyy-MM-dd") + " 23:59:59";
        }


        /**------------------------------X轴数值--------------------------------------**/
        String[] months = new String[12];
        if (StringUtils.isEmpty(brokenLineDataParameter.getYear())) {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -12);

            for (int i = 0; i < 12; i++) {
                calendar.add(Calendar.MONTH, 1);
                String date = new SimpleDateFormat("yyyy-MM").format(calendar.getTime());
                months[i] = date;
            }
        } else {
            months[0] = brokenLineDataParameter.getYear() + "-01";
            months[1] = brokenLineDataParameter.getYear() + "-02";
            months[2] = brokenLineDataParameter.getYear() + "-03";
            months[3] = brokenLineDataParameter.getYear() + "-04";
            months[4] = brokenLineDataParameter.getYear() + "-05";
            months[5] = brokenLineDataParameter.getYear() + "-06";
            months[6] = brokenLineDataParameter.getYear() + "-07";
            months[7] = brokenLineDataParameter.getYear() + "-08";
            months[8] = brokenLineDataParameter.getYear() + "-09";
            months[9] = brokenLineDataParameter.getYear() + "-10";
            months[10] = brokenLineDataParameter.getYear() + "-11";
            months[11] = brokenLineDataParameter.getYear() + "-12";
        }
        /**------------------------------X轴数值--------------------------------------**/

        if (brokenLineDataParameter.getType() == null) {
            brokenLineDataParameter.setType(2);
        }

        List<Map<String, Long>> map = null;
        List<Map<String, BigDecimal>> kpiMap = null;
        Long[] value = new Long[12];
        BigDecimal[] rateValue = new BigDecimal[12];

        //率的统计
        List<Map<String, Long>> oldRateMap = null;
        List<Map<String, Long>> newRateMap = null;
        Long[] oldValue = new Long[12];
        Long[] newValue = new Long[12];

        //线索数
        List<Map<String, Long>> leads = this.crmInstrumentMapper.queryLeadsCountByDate(queryStartDate, queryEndDate, userIdList, brokenLineDataParameter.getDataFrom());
        if (brokenLineDataParameter.getType() != null) {
            switch (BrokenLineDataEnum.parse(brokenLineDataParameter.getType())) {
                case LEADS_NUM:
                    leads = this.crmInstrumentMapper.queryLeadsCountByDate(queryStartDate, queryEndDate, userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < months.length; i++) {
                        if (leads != null && leads.size() > 0) {
                            for (Map<String, Long> map1 : leads) {
                                if (months[i].equals(map1.get("ym"))) {
                                    value[i] = map1.get("num");
                                    break;
                                } else {
                                    value[i] = 0L;
                                }
                            }
                        } else {
                            value[i] = 0L;
                        }
                    }
                    break;
                case BAOKE_NUM:
                    map = this.crmInstrumentMapper.queryBaoKeCountByDate(queryStartDate, queryEndDate, userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < months.length; i++) {
                        if (map != null && map.size() > 0) {
                            for (Map<String, Long> map1 : map) {
                                if (months[i].equals(map1.get("ym"))) {
                                    value[i] = map1.get("num");
                                    break;
                                } else {
                                    value[i] = 0L;
                                }
                            }
                        } else {
                            value[i] = 0L;
                        }
                    }
                    break;
                case BAOKE_RATE:
                    //报课数据信息
                    oldRateMap = this.crmInstrumentMapper.queryBaoKeCountByDate(queryStartDate, queryEndDate, userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < months.length; i++) {
                        if (oldRateMap != null && oldRateMap.size() > 0) {
                            for (Map<String, Long> map1 : oldRateMap) {
                                if (months[i].equals(map1.get("ym"))) {
                                    oldValue[i] = map1.get("num");
                                    break;
                                } else {
                                    oldValue[i] = 0L;
                                }
                            }
                        } else {
                            oldValue[i] = 0L;
                        }
                    }

                    //线索数据信息
                    newRateMap = this.crmInstrumentMapper.queryLeadsCountByDate(queryStartDate, queryEndDate, userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < months.length; i++) {
                        if (newRateMap != null && newRateMap.size() > 0) {
                            for (Map<String, Long> map1 : newRateMap) {
                                if (months[i].equals(map1.get("ym"))) {
                                    newValue[i] = map1.get("num");
                                    break;
                                } else {
                                    newValue[i] = 0L;
                                }
                            }
                        } else {
                            newValue[i] = 0L;
                        }
                    }

                    //获取率的数据
                    for (int i = 0; i < oldValue.length; i++) {
                        if (newValue[i] == 0) {
                            rateValue[i] = new BigDecimal(0);
                        } else {
                            BigDecimal s = new BigDecimal(oldValue[i]).divide(new BigDecimal(newValue[i]), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
                            NumberFormat nf = NumberFormat.getNumberInstance();
                            nf.setMaximumFractionDigits(2);
                            System.out.println(nf.format(s));
                            rateValue[i] = new BigDecimal(nf.format(s));
                        }

                    }
                    break;
                case ADD_FRIEND_NUM:
                    map = this.crmInstrumentMapper.queryAddWechatCountByDate(queryStartDate, queryEndDate, userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < months.length; i++) {
                        if (map != null && map.size() > 0) {
                            for (Map<String, Long> map1 : map) {
                                if (months[i].equals(map1.get("ym"))) {
                                    value[i] = map1.get("num");
                                    break;
                                } else {
                                    value[i] = 0L;
                                }
                            }
                        } else {
                            value[i] = 0L;
                        }
                    }
                    break;
                case ADD_FRIEND_RATE:
                    oldRateMap = this.crmInstrumentMapper.queryAddWechatCountByDate(queryStartDate, queryEndDate, userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < months.length; i++) {
                        if (oldRateMap != null && oldRateMap.size() > 0) {
                            for (Map<String, Long> map1 : oldRateMap) {
                                if (months[i].equals(map1.get("ym"))) {
                                    oldValue[i] = map1.get("num");
                                    break;
                                } else {
                                    oldValue[i] = 0L;
                                }
                            }
                        } else {
                            oldValue[i] = 0L;
                        }
                    }

                    //线索数据信息
                    newRateMap = this.crmInstrumentMapper.queryLeadsCountByDate(queryStartDate, queryEndDate, userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < months.length; i++) {
                        if (newRateMap != null && newRateMap.size() > 0) {
                            for (Map<String, Long> map1 : newRateMap) {
                                if (months[i].equals(map1.get("ym"))) {
                                    newValue[i] = map1.get("num");
                                    break;
                                } else {
                                    newValue[i] = 0L;
                                }
                            }
                        } else {
                            newValue[i] = 0L;
                        }
                    }

                    //获取率的数据
                    for (int i = 0; i < oldValue.length; i++) {
                        if (newValue[i] == 0) {
                            rateValue[i] = new BigDecimal(0);
                        } else {
                            BigDecimal s = new BigDecimal(oldValue[i]).divide(new BigDecimal(newValue[i]), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
                            NumberFormat nf = NumberFormat.getNumberInstance();
                            nf.setMaximumFractionDigits(2);
                            System.out.println(nf.format(s));
                            rateValue[i] = new BigDecimal(nf.format(s));
                        }

                    }
                    break;
                case ADD_GROUP_NUM:
                    map = this.crmInstrumentMapper.queryAddGroupCountByDate(queryStartDate, queryEndDate, userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < months.length; i++) {
                        if (map != null && map.size() > 0) {
                            for (Map<String, Long> map1 : map) {
                                if (months[i].equals(map1.get("ym"))) {
                                    value[i] = map1.get("num");
                                    break;
                                } else {
                                    value[i] = 0L;
                                }
                            }
                        } else {
                            value[i] = 0L;
                        }
                    }
                    break;
                case ADD_GROUP_RATE:
                    oldRateMap = this.crmInstrumentMapper.queryAddGroupCountByDate(queryStartDate, queryEndDate, userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < months.length; i++) {
                        if (oldRateMap != null && oldRateMap.size() > 0) {
                            for (Map<String, Long> map1 : oldRateMap) {
                                if (months[i].equals(map1.get("ym"))) {
                                    oldValue[i] = map1.get("num");
                                    break;
                                } else {
                                    oldValue[i] = 0L;
                                }
                            }
                        } else {
                            oldValue[i] = 0L;
                        }
                    }

                    //线索数据信息
                    newRateMap = this.crmInstrumentMapper.queryLeadsCountByDate(queryStartDate, queryEndDate, userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < months.length; i++) {
                        if (newRateMap != null && newRateMap.size() > 0) {
                            for (Map<String, Long> map1 : newRateMap) {
                                if (months[i].equals(map1.get("ym"))) {
                                    newValue[i] = map1.get("num");
                                    break;
                                } else {
                                    newValue[i] = 0L;
                                }
                            }
                        } else {
                            newValue[i] = 0L;
                        }
                    }

                    //获取率的数据
                    for (int i = 0; i < oldValue.length; i++) {
                        if (newValue[i] == 0) {
                            rateValue[i] = new BigDecimal(0);
                        } else {
                            BigDecimal s = new BigDecimal(oldValue[i]).divide(new BigDecimal(newValue[i]), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
                            NumberFormat nf = NumberFormat.getNumberInstance();
                            nf.setMaximumFractionDigits(2);
                            System.out.println(nf.format(s));
                            rateValue[i] = new BigDecimal(nf.format(s));
                        }

                    }
                    break;
                case DEAL_NUM:
                    map = this.crmInstrumentMapper.queryDealCountByDate(queryStartDate, queryEndDate, userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < months.length; i++) {
                        if (map != null && map.size() > 0) {
                            for (Map<String, Long> map1 : map) {
                                if (months[i].equals(map1.get("ym"))) {
                                    value[i] = map1.get("num");
                                    break;
                                } else {
                                    value[i] = 0L;
                                }
                            }
                        } else {
                            value[i] = 0L;
                        }
                    }
                    break;
                case DEAL_RATE:
                    oldRateMap = this.crmInstrumentMapper.queryDealCountByDate(queryStartDate, queryEndDate, userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < months.length; i++) {
                        if (oldRateMap != null && oldRateMap.size() > 0) {
                            for (Map<String, Long> map1 : oldRateMap) {
                                if (months[i].equals(map1.get("ym"))) {
                                    oldValue[i] = map1.get("num");
                                    break;
                                } else {
                                    oldValue[i] = 0L;
                                }
                            }
                        } else {
                            oldValue[i] = 0L;
                        }
                    }

                    //线索数据信息
                    newRateMap = this.crmInstrumentMapper.queryLeadsCountByDate(queryStartDate, queryEndDate, userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < months.length; i++) {
                        if (newRateMap != null && newRateMap.size() > 0) {
                            for (Map<String, Long> map1 : newRateMap) {
                                if (months[i].equals(map1.get("ym"))) {
                                    newValue[i] = map1.get("num");
                                    break;
                                } else {
                                    newValue[i] = 0L;
                                }
                            }
                        } else {
                            newValue[i] = 0L;
                        }
                    }

                    //获取率的数据
                    for (int i = 0; i < oldValue.length; i++) {
                        if (newValue[i] == 0) {
                            rateValue[i] = new BigDecimal(0);
                        } else {
                            BigDecimal s = new BigDecimal(oldValue[i]).divide(new BigDecimal(newValue[i]), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
                            NumberFormat nf = NumberFormat.getNumberInstance();
                            nf.setMaximumFractionDigits(2);
                            System.out.println(nf.format(s));
                            rateValue[i] = new BigDecimal(nf.format(s));
                        }

                    }
                    break;
                case KPI:
                    kpiMap = this.crmInstrumentMapper.queryKPIDataByDate(queryStartDate, queryEndDate, userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < months.length; i++) {
                        if (kpiMap != null && kpiMap.size() > 0) {
                            for (Map<String, BigDecimal> map1 : kpiMap) {
                                if (months[i].equals(map1.get("ym"))) {
//                                    BigDecimal bigDecimal = new BigDecimal();
                                    rateValue[i] = map1.get("num");
                                    break;
                                } else {
                                    rateValue[i] = new BigDecimal(0);
                                }
                            }
                        } else {
                            rateValue[i] = new BigDecimal(0);
                        }
                    }
                    break;
            }
        }

        String queryDate = null;
        if (StringUtils.isNotEmpty(brokenLineDataParameter.getYear())) {
            queryDate = brokenLineDataParameter.getYear() + "-12-31";
        }
        /**----------------------------------------------------按年度统计折线数据信息-start--------------------------------------------------------------**/

        Map<String, Object> yearData = new HashMap<>();

        yearData.put("xAxis", months);
        if ((brokenLineDataParameter.getType() == 1 || brokenLineDataParameter.getType() == 2 || brokenLineDataParameter.getType() == 4 || brokenLineDataParameter.getType() == 6 || brokenLineDataParameter.getType() == 8)) {
            yearData.put("values", value);
        } else {
            yearData.put("values", rateValue);
        }

        /**----------------------------------------------------按年度统计折线数据信息-end--------------------------------------------------------------**/

        return new JSONObject().fluentPut("leadsStatistics", yearData);
    }

    /**
     * 根据期数查询数据信息
     *
     * @param brokenLineDataParameter
     * @return
     */
    public JSONObject queryPeriodsStatisticsData(BrokenLineDataParameter brokenLineDataParameter) {

        if (StringUtils.isEmpty(brokenLineDataParameter.getDataFrom())) {
            brokenLineDataParameter.setDataFrom("涵品");
        }

        //循环范围内期数
        Integer[] periodsArr = {};
        int count = 0;
        int arrIndex = 0;

        List<Long> userIdList = new ArrayList<>();
        if (brokenLineDataParameter.getDeptId() == null) {
            if (UserUtil.isAdmin()) {
                userIdList.addAll(adminService.queryUserList());
            } else {
                userIdList.addAll(adminService.queryChildUserId(UserUtil.getUserId()));
                userIdList.add(UserUtil.getUserId());
            }
        } else {
            AdminUserBO adminUserBO = new AdminUserBO();
            adminUserBO.setDeptId(brokenLineDataParameter.getDeptId());
            BasePage<AdminUserEntityVO> basePageResult = SpringUtils.getBean(AdminService.class).queryUserList(adminUserBO);
            List<AdminUserEntityVO> list = basePageResult.getList();
            for (AdminUserEntityVO adminUserVO : list) {
                userIdList.add(adminUserVO.getUserId());
            }
        }

        //起始 结束 期数 都有
        if (brokenLineDataParameter.getStartPeriods() != null && brokenLineDataParameter.getEndPeriods() != null) {
            if (brokenLineDataParameter.getEndPeriods().compareTo(brokenLineDataParameter.getStartPeriods()) < 0) {
                throw new CrmException(CrmCodeEnum.CRM_PERIODS_BEGIN_IS_LESS_THAN_END);
            }
            periodsArr = new Integer[brokenLineDataParameter.getEndPeriods() - brokenLineDataParameter.getStartPeriods() + 1];
            for (int i = brokenLineDataParameter.getStartPeriods(); i <= brokenLineDataParameter.getEndPeriods(); i++) {
                periodsArr[count] = i;
                count++;
                arrIndex += 1;
            }
            //只有起始期数
        } else if (brokenLineDataParameter.getStartPeriods() != null) {
            periodsArr = new Integer[8];
            for (int i = 0; i < 8; i++) {
                periodsArr[i] = brokenLineDataParameter.getStartPeriods() + i;
                arrIndex += 1;
            }
            //只有结束期数
        } else if (brokenLineDataParameter.getEndPeriods() != null && brokenLineDataParameter.getEndPeriods().compareTo(8) >= 0) {
            periodsArr = new Integer[8];
            for (int i = 7; i >= 0; i--) {
                periodsArr[7 - i] = brokenLineDataParameter.getEndPeriods() - i;
                arrIndex += 1;
            }
            //默认期数
        } else {
            List<Integer> periods = this.crmInstrumentMapper.queryDefaultPeriods(brokenLineDataParameter.getDataFrom());
            arrIndex = periods.size();
            periodsArr = new Integer[periods.size()];
            for (int i = 0; i < periods.size(); i++) {
                periodsArr[i] = periods.get(i);
            }
        }

        if (periodsArr.length > 16) {
            throw new CrmException(CrmCodeEnum.CRM_PERIODS_IS_TOO_LONG);
        }

        List<Map<String, Long>> map = null;
        List<Map<String, BigDecimal>> kpiMap = null;
        Long[] value = new Long[arrIndex];
        BigDecimal[] rateValue = new BigDecimal[arrIndex];

        //率的统计
        List<Map<String, Long>> oldRateMap = null;
        List<Map<String, Long>> newRateMap = null;
        Long[] oldValue = new Long[arrIndex];
        Long[] newValue = new Long[arrIndex];


        //线索数
        List<Map<String, Long>> leads = this.crmInstrumentMapper.queryLeadsCountByPeriods(Arrays.asList(periodsArr), userIdList, brokenLineDataParameter.getDataFrom());

        if (brokenLineDataParameter.getType() != null) {
            switch (BrokenLineDataEnum.parse(brokenLineDataParameter.getType())) {
                case LEADS_NUM:
                    leads = this.crmInstrumentMapper.queryLeadsCountByPeriods(Arrays.asList(periodsArr), userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < periodsArr.length; i++) {
                        if (leads != null && leads.size() > 0) {
                            for (Map<String, Long> map1 : leads) {
                                if (String.valueOf(periodsArr[i]).equals(map1.get("qs"))) {
                                    value[i] = map1.get("num");
                                    break;
                                } else {
                                    value[i] = 0L;
                                }
                            }
                        } else {
                            value[i] = 0L;
                        }
                    }
                    break;
                case BAOKE_NUM:
                    map = this.crmInstrumentMapper.queryBaoKeCountByPeriods(Arrays.asList(periodsArr), userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < periodsArr.length; i++) {
                        if (map != null && map.size() > 0) {
                            for (Map<String, Long> map1 : map) {
                                if (String.valueOf(periodsArr[i]).equals(map1.get("qs"))) {
                                    value[i] = map1.get("num");
                                    break;
                                } else {
                                    value[i] = 0L;
                                }
                            }
                        } else {
                            value[i] = 0L;
                        }
                    }
                    break;
                case BAOKE_RATE:
                    //报课数据信息
                    oldRateMap = this.crmInstrumentMapper.queryBaoKeCountByPeriods(Arrays.asList(periodsArr), userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < periodsArr.length; i++) {
                        if (oldRateMap != null && oldRateMap.size() > 0) {
                            for (Map<String, Long> map1 : oldRateMap) {
                                if (String.valueOf(periodsArr[i]).equals(map1.get("qs"))) {
                                    oldValue[i] = map1.get("num");
                                    break;
                                } else {
                                    oldValue[i] = 0L;
                                }
                            }
                        } else {
                            oldValue[i] = 0L;
                        }
                    }

                    //线索数据信息
                    newRateMap = this.crmInstrumentMapper.queryLeadsCountByPeriods(Arrays.asList(periodsArr), userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < periodsArr.length; i++) {
                        if (newRateMap != null && newRateMap.size() > 0) {
                            for (Map<String, Long> map1 : newRateMap) {
                                if (String.valueOf(periodsArr[i]).equals(map1.get("qs"))) {
                                    newValue[i] = map1.get("num");
                                    break;
                                } else {
                                    newValue[i] = 0L;
                                }
                            }
                        } else {
                            newValue[i] = 0L;
                        }
                    }

                    //获取率的数据
                    for (int i = 0; i < oldValue.length; i++) {
                        if (newValue[i] == 0) {
                            rateValue[i] = new BigDecimal(0);
                        } else {
                            BigDecimal s = new BigDecimal(oldValue[i]).divide(new BigDecimal(newValue[i]), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
                            NumberFormat nf = NumberFormat.getNumberInstance();
                            nf.setMaximumFractionDigits(2);
                            System.out.println(nf.format(s));
                            rateValue[i] = new BigDecimal(nf.format(s));
                        }

                    }

                    break;
                case ADD_FRIEND_NUM:
                    map = this.crmInstrumentMapper.queryAddWechatCountByPeriods(Arrays.asList(periodsArr), userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < periodsArr.length; i++) {
                        if (map != null && map.size() > 0) {
                            for (Map<String, Long> map1 : map) {
                                if (String.valueOf(periodsArr[i]).equals(map1.get("qs"))) {
                                    value[i] = map1.get("num");
                                    break;
                                } else {
                                    value[i] = 0L;
                                }
                            }
                        } else {
                            value[i] = 0L;
                        }
                    }
                    break;
                case ADD_FRIEND_RATE:
                    oldRateMap = this.crmInstrumentMapper.queryAddWechatCountByPeriods(Arrays.asList(periodsArr), userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < periodsArr.length; i++) {
                        if (oldRateMap != null && oldRateMap.size() > 0) {
                            for (Map<String, Long> map1 : oldRateMap) {
                                if (String.valueOf(periodsArr[i]).equals(map1.get("qs"))) {
                                    oldValue[i] = map1.get("num");
                                    break;
                                } else {
                                    oldValue[i] = 0L;
                                }
                            }
                        } else {
                            oldValue[i] = 0L;
                        }
                    }

                    //线索数据信息
                    newRateMap = this.crmInstrumentMapper.queryLeadsCountByPeriods(Arrays.asList(periodsArr), userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < periodsArr.length; i++) {
                        if (newRateMap != null && newRateMap.size() > 0) {
                            for (Map<String, Long> map1 : newRateMap) {
                                if (String.valueOf(periodsArr[i]).equals(map1.get("qs"))) {
                                    newValue[i] = map1.get("num");
                                    break;
                                } else {
                                    newValue[i] = 0L;
                                }
                            }
                        } else {
                            newValue[i] = 0L;
                        }
                    }

                    //获取率的数据
                    for (int i = 0; i < oldValue.length; i++) {
                        if (newValue[i] == 0) {
                            rateValue[i] = new BigDecimal(0);
                        } else {
                            BigDecimal s = new BigDecimal(oldValue[i]).divide(new BigDecimal(newValue[i]), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
                            NumberFormat nf = NumberFormat.getNumberInstance();
                            nf.setMaximumFractionDigits(2);
                            System.out.println(nf.format(s));
                            rateValue[i] = new BigDecimal(nf.format(s));
                        }

                    }
                    break;
                case ADD_GROUP_NUM:
                    map = this.crmInstrumentMapper.queryAddGroupCountByPeriods(Arrays.asList(periodsArr), userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < periodsArr.length; i++) {
                        if (map != null && map.size() > 0) {
                            for (Map<String, Long> map1 : map) {
                                if (String.valueOf(periodsArr[i]).equals(map1.get("qs"))) {
                                    value[i] = map1.get("num");
                                    break;
                                } else {
                                    value[i] = 0L;
                                }
                            }
                        } else {
                            value[i] = 0L;
                        }
                    }
                    break;
                case ADD_GROUP_RATE:
                    oldRateMap = this.crmInstrumentMapper.queryAddGroupCountByPeriods(Arrays.asList(periodsArr), userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < periodsArr.length; i++) {
                        if (oldRateMap != null && oldRateMap.size() > 0) {
                            for (Map<String, Long> map1 : oldRateMap) {
                                if (String.valueOf(periodsArr[i]).equals(map1.get("qs"))) {
                                    oldValue[i] = map1.get("num");
                                    break;
                                } else {
                                    oldValue[i] = 0L;
                                }
                            }
                        } else {
                            oldValue[i] = 0L;
                        }
                    }

                    //线索数据信息
                    newRateMap = this.crmInstrumentMapper.queryLeadsCountByPeriods(Arrays.asList(periodsArr), userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < periodsArr.length; i++) {
                        if (newRateMap != null && newRateMap.size() > 0) {
                            for (Map<String, Long> map1 : newRateMap) {
                                if (String.valueOf(periodsArr[i]).equals(map1.get("qs"))) {
                                    newValue[i] = map1.get("num");
                                    break;
                                } else {
                                    newValue[i] = 0L;
                                }
                            }
                        } else {
                            newValue[i] = 0L;
                        }
                    }

                    //获取率的数据
                    for (int i = 0; i < oldValue.length; i++) {
                        if (newValue[i] == 0) {
                            rateValue[i] = new BigDecimal(0);
                        } else {
                            BigDecimal s = new BigDecimal(oldValue[i]).divide(new BigDecimal(newValue[i]), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
                            NumberFormat nf = NumberFormat.getNumberInstance();
                            nf.setMaximumFractionDigits(2);
                            System.out.println(nf.format(s));
                            rateValue[i] = new BigDecimal(nf.format(s));
                        }

                    }
                    break;
                case DEAL_NUM:
                    map = this.crmInstrumentMapper.queryDealCountByPeriods(Arrays.asList(periodsArr), userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < periodsArr.length; i++) {
                        if (map != null && map.size() > 0) {
                            for (Map<String, Long> map1 : map) {
                                if (String.valueOf(periodsArr[i]).equals(map1.get("qs"))) {
                                    value[i] = map1.get("num");
                                    break;
                                } else {
                                    value[i] = 0L;
                                }
                            }
                        } else {
                            value[i] = 0L;
                        }
                    }
                    break;
                case DEAL_RATE:

                    oldRateMap = this.crmInstrumentMapper.queryDealCountByPeriods(Arrays.asList(periodsArr), userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < periodsArr.length; i++) {
                        if (oldRateMap != null && oldRateMap.size() > 0) {
                            for (Map<String, Long> map1 : oldRateMap) {
                                if (String.valueOf(periodsArr[i]).equals(map1.get("qs"))) {
                                    oldValue[i] = map1.get("num");
                                    break;
                                } else {
                                    oldValue[i] = 0L;
                                }
                            }
                        } else {
                            oldValue[i] = 0L;
                        }
                    }

                    //线索数据信息
                    newRateMap = this.crmInstrumentMapper.queryLeadsCountByPeriods(Arrays.asList(periodsArr), userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < periodsArr.length; i++) {
                        if (newRateMap != null && newRateMap.size() > 0) {
                            for (Map<String, Long> map1 : newRateMap) {
                                if (String.valueOf(periodsArr[i]).equals(map1.get("qs"))) {
                                    newValue[i] = map1.get("num");
                                    break;
                                } else {
                                    newValue[i] = 0L;
                                }
                            }
                        } else {
                            newValue[i] = 0L;
                        }
                    }

                    //获取率的数据
                    for (int i = 0; i < oldValue.length; i++) {
                        if (newValue[i] == 0) {
                            rateValue[i] = new BigDecimal(0);
                        } else {
                            BigDecimal s = new BigDecimal(oldValue[i]).divide(new BigDecimal(newValue[i]), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
                            NumberFormat nf = NumberFormat.getNumberInstance();
                            nf.setMaximumFractionDigits(2);
                            System.out.println(nf.format(s));
                            rateValue[i] = new BigDecimal(nf.format(s));
                        }

                    }
                    break;
                case KPI:
                    kpiMap = this.crmInstrumentMapper.queryKPIDataByPeriods(Arrays.asList(periodsArr), userIdList, brokenLineDataParameter.getDataFrom());
                    for (int i = 0; i < periodsArr.length; i++) {
                        if (kpiMap != null && kpiMap.size() > 0) {
                            for (Map<String, BigDecimal> map1 : kpiMap) {
                                if (String.valueOf(periodsArr[i]).equals(map1.get("qs"))) {
//                                    BigDecimal bigDecimal = new BigDecimal();
                                    rateValue[i] = map1.get("num");
                                    break;
                                } else {
                                    rateValue[i] = new BigDecimal(0);
                                }
                            }
                        } else {
                            rateValue[i] = new BigDecimal(0);
                        }
                    }
                    break;
            }
        }

        /**----------------------------------------------------按期数统计折线数据信息-start--------------------------------------------------------------**/

        Map<String, Object> periodsData = new HashMap<>();

        periodsData.put("xAxis", periodsArr);

        if ((brokenLineDataParameter.getType() == 1 || brokenLineDataParameter.getType() == 2 || brokenLineDataParameter.getType() == 4 || brokenLineDataParameter.getType() == 6 || brokenLineDataParameter.getType() == 8)) {
            periodsData.put("values", value);
        } else {
            periodsData.put("values", rateValue);
        }
        /**----------------------------------------------------按期数统计折线数据信息-end--------------------------------------------------------------**/

        return new JSONObject().fluentPut("customerStatistics", periodsData);
    }

    /**
     * 市场部仪表盘的数据
     *
     * @param biParams
     * @return
     * @throws Exception
     */
    @Override
    public MarketingDepartmentDashBoardVO queryMarketingDepartmentSalesData(BiParams biParams) throws Exception {

        MarketingDepartmentDashBoardVO dashBoardVO = new MarketingDepartmentDashBoardVO();

        //查询时间的范围
        BiTimeUtil.BiTimeEntity biTimeEntity = BiTimeUtil.analyzeTime(biParams);
        //环比时间范围
        BiTimeUtil.BiTimeEntity momTimeRangeEntity = CrmInstrumentServiceImpl.moM(biParams.getType(), biParams.getStartTime(),
                biParams.getEndTime());
        //当前用户可查询对象，用来区分查询范围
        BiAuthority biAuthority = handleDataType(biParams);

        //限制范围内的线索总数
        Integer leadsCount = crmInstrumentMapper.queryLeadsCount(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams);
        biParams.setRepetition("否");
        Integer leadsCount_nocf = crmInstrumentMapper.queryLeadsCount(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams);
        biParams.setRepetition("是");
        Integer leadsCount_cf = crmInstrumentMapper.queryLeadsCount(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams);


        BiParams biParams_nocf = new BiParams();
        BiParams biParams_cf = new BiParams();
        biParams.setRepetition("");
        BeanUtils.copyProperties(biParams, biParams_nocf);
        biParams_nocf.setRepetition("否");
        BeanUtils.copyProperties(biParams, biParams_cf);
        biParams_cf.setRepetition("是");

        //当前线索数
        MarketingDepartmentDashBoardVO.CustomerData customerData = this.getMarketingDepartmentCustomerData(biTimeEntity, momTimeRangeEntity,
                biAuthority, leadsCount, leadsCount_nocf, leadsCount_cf, biParams.getDataForm(), biParams, biParams_nocf, biParams_cf);
        dashBoardVO.setCustomerData(customerData);
//        runAsync
//        CompletableFuture<Void> customer = CompletableFuture.runAsync(() -> {
//            MarketingDepartmentDashBoardVO.CustomerData customerData = this.getMarketingDepartmentCustomerData(biTimeEntity, momTimeRangeEntity,
//                    biAuthority, leadsCount, leadsCount_nocf, leadsCount_cf, biParams.getDataForm(), biParams, biParams_nocf, biParams_cf);
//            dashBoardVO.setCustomerData(customerData);
//        }, executor);

        //客服加微信数
        biParams.setRepetition("");
        BeanUtils.copyProperties(biParams, biParams_nocf);
        biParams_nocf.setRepetition("否");
        BeanUtils.copyProperties(biParams, biParams_cf);
        biParams_cf.setRepetition("是");
        MarketingDepartmentDashBoardVO.AddWechatData addWechatData = this.getMarketingDepartmentAddWechatData(biTimeEntity, momTimeRangeEntity,
                biAuthority, leadsCount, leadsCount_nocf, leadsCount_cf, biParams.getDataForm(), biParams, biParams_nocf, biParams_cf);
        dashBoardVO.setAddWechatData(addWechatData);
//        CompletableFuture<Void> addWechat = CompletableFuture.runAsync(() -> {
//            MarketingDepartmentDashBoardVO.AddWechatData addWechatData = this.getMarketingDepartmentAddWechatData(biTimeEntity, momTimeRangeEntity,
//                    biAuthority, leadsCount, leadsCount_nocf, leadsCount_cf, biParams.getDataForm(), biParams, biParams_nocf, biParams_cf);
//            dashBoardVO.setAddWechatData(addWechatData);
//        }, executor);


        //客户报课数
        biParams.setRepetition("");
        BeanUtils.copyProperties(biParams, biParams_nocf);
        biParams_nocf.setRepetition("否");
        BeanUtils.copyProperties(biParams, biParams_cf);
        biParams_cf.setRepetition("是");
        MarketingDepartmentDashBoardVO.CustomerApplyData customerApplyData = this.getMarketingDepartmentCustomerApplyData(biTimeEntity,
                momTimeRangeEntity, biAuthority, leadsCount, leadsCount_nocf, leadsCount_cf, biParams.getDataForm(), biParams, biParams_nocf, biParams_cf);
        dashBoardVO.setCustomerApplyData(customerApplyData);
        CompletableFuture<Void> customerApply = CompletableFuture.runAsync(() -> {

//            MarketingDepartmentDashBoardVO.CustomerApplyData customerApplyData = this.getMarketingDepartmentCustomerApplyData(biTimeEntity,
//                    momTimeRangeEntity, biAuthority, leadsCount, leadsCount_nocf, leadsCount_cf, biParams.getDataForm(), biParams, biParams_nocf, biParams_cf);
//            dashBoardVO.setCustomerApplyData(customerApplyData);
        }, executor);


        //成交表单数
        biParams.setRepetition("");
        BeanUtils.copyProperties(biParams, biParams_nocf);
        biParams_nocf.setRepetition("否");
        BeanUtils.copyProperties(biParams, biParams_cf);
        biParams_cf.setRepetition("是");
        MarketingDepartmentDashBoardVO.DealFormData dealFormData = this.queryDealFormData(biTimeEntity,
                momTimeRangeEntity, biAuthority, leadsCount, leadsCount_nocf, leadsCount_cf, biParams.getDataForm(), biParams, biParams_nocf, biParams_cf);
        dashBoardVO.setDealFormData(dealFormData);
//        CompletableFuture<Void> dealForm = CompletableFuture.runAsync(() -> {
//
//            MarketingDepartmentDashBoardVO.DealFormData dealFormData = this.queryDealFormData(biTimeEntity,
//                    momTimeRangeEntity, biAuthority, leadsCount, leadsCount_nocf, leadsCount_cf, biParams.getDataForm(), biParams, biParams_nocf, biParams_cf);
//            dashBoardVO.setDealFormData(dealFormData);
//        }, executor);

//        CompletableFuture.allOf(customer, addWechat, customerApply, dealForm).exceptionally((e) -> {
//            e.printStackTrace();
//            return null;
//        }).join();

        return dashBoardVO;
    }



    /**
     * 成交表单数
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public MarketingDepartmentDashBoardVO.DealFormData queryDealFormData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                         BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                         BiAuthority biAuthority,
                                                                         Integer customerCount, Integer leadsCountNoCf, Integer leadsCountCf, String dataFrom, BiParams biParams, BiParams biParams_nocf, BiParams biParams_cf) {

        Integer dealForm = crmInstrumentMapper.queryDealFormCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity, biParams);


        Integer dealForm_NoCf = crmInstrumentMapper.queryDealFormCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity, biParams_nocf);

        Integer dealForm_Cf = crmInstrumentMapper.queryDealFormCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity, biParams_cf);

        String mom = "时间范围为全部时，没有环比";
        String mom2 = "时间范围为全部时，没有环比";
        String mom3 = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            Integer salesDealFromMom = crmInstrumentMapper.queryDealFormCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity, biParams);
            mom = calculateMom(dealForm, salesDealFromMom);

            Integer salesDealFromMom_NoCf = crmInstrumentMapper.queryDealFormCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity, biParams_nocf);
            mom2 = calculateMom(dealForm_NoCf, salesDealFromMom_NoCf);

            Integer salesDealFromMom_Cf = crmInstrumentMapper.queryDealFormCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity, biParams_cf);
            mom3 = calculateMom(dealForm_Cf, salesDealFromMom_Cf);
        }

        String rate = this.calculateRate(dealForm, customerCount);
        String rate2 = this.calculateRate(dealForm_NoCf, leadsCountNoCf);
        String rate3 = this.calculateRate(dealForm_Cf, leadsCountCf);

        MarketingDepartmentDashBoardVO.DealFormData dealFormData = new MarketingDepartmentDashBoardVO.DealFormData();
        dealFormData.setData(dealForm);
        dealFormData.setData2(dealForm_NoCf);
        dealFormData.setData3(dealForm_Cf);
        if (mom.indexOf("%") != -1) {
            dealFormData.setMom(Double.valueOf(mom.split("%")[0]));
        } else {
            dealFormData.setMom(0);
        }
        if (mom2.indexOf("%") != -1) {
            dealFormData.setMom2(Double.valueOf(mom2.split("%")[0]));
        } else {
            dealFormData.setMom2(0);
        }
        if (mom3.indexOf("%") != -1) {
            dealFormData.setMom3(Double.valueOf(mom3.split("%")[0]));
        } else {
            dealFormData.setMom3(0);
        }
        dealFormData.setRate(rate);
        dealFormData.setRate2(rate2);
        dealFormData.setRate3(rate3);

        dealFormData.setLabel("成交表单数");
        dealFormData.setTitle("成交表单数");
        dealFormData.setType("leads");
        dealFormData.setPlaTip("leadsTip");
        dealFormData.setLabelValue(1);

        return dealFormData;
    }

    /**
     * 获取当前近intervals天的日期
     *
     * @param intervals 查询的天数
     * @return
     */
    public List<String> getDays(int intervals) {
        List<String> pastDaysList = new ArrayList<>();
        for (int i = intervals - 1; i >= 0; i--) {
            pastDaysList.add(getPastDate(i));
        }
        return pastDaysList;
    }

    public static String getPastDate(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - past);
        Date today = calendar.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String result = format.format(today);
        return result;
    }

    /**
     * 查询每日表单数量
     *
     * @param biParams
     * @return
     */
    public JSONObject queryEverydayFormCount(BiParams biParams) {
        BiAuthority biAuthority = handleDataType(biParams);
        List<String> pastDaysList = getDays(15);


        Map<String, Object> data = new HashMap<>();
        data.put("userIds", biAuthority.getUserIds());
        data.put("periods", biParams.getPeriods());
        data.put("categories", biParams.getCategories());
        data.put("salesType", biParams.getSalesType());
        Date endTime = new Date();
        Date startTime = DateUtils.addDays(endTime, -14);
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(startTime);
        cal1.set(Calendar.HOUR_OF_DAY, 0);
        cal1.set(Calendar.MINUTE, 0);
        cal1.set(Calendar.SECOND, 0);
//        cal1.set(Calendar.MILLISECOND, 0);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(endTime);
        cal2.set(Calendar.HOUR_OF_DAY, 23);
        cal2.set(Calendar.MINUTE, 59);
        cal2.set(Calendar.SECOND, 59);
//        cal2.set(Calendar.MILLISECOND, 0);
        data.put("startTime", cal1.getTime());
        data.put("endTime", cal2.getTime());
        Map<String, Object> formCountMap = new HashMap<>();
        formCountMap.put("days", pastDaysList);

        List<Integer> daysFormCount = getListCount(crmInstrumentMapper.queryDaysFormCount(data));
        formCountMap.put("daysFormCount",daysFormCount);

        List<Integer> daysAddWechatCount = getListCount(crmInstrumentMapper.queryDaysAddWechatCount(data));
        formCountMap.put("daysAddWechatCount", daysAddWechatCount);
        List<Integer> daysReportClassCount = getListCount(crmInstrumentMapper.queryDaysReportClassCount(data));

        formCountMap.put("daysReportClassCount", daysReportClassCount);
        return new JSONObject().fluentPut("daysCount", formCountMap);
    }

    /**
     * 自动填充日期
     * @param list
     * @return
     */
    public List<Integer> getListCount(List<JSONObject> list) {
        List<Integer> daysCount = new ArrayList<>();
        List<String> pastDaysList = getDays(15);
        for (String date : pastDaysList) {
            Boolean is = false;
            Integer count = 0;
            for (JSONObject jsonObject : list) {
                String leadsCreateTime = jsonObject.getString("leadsCreateTime");
                count = jsonObject.getInteger("count");
                if (date.equals(leadsCreateTime)) {
                    is = true;
                    break;
                }
            }
            if (is) {
                daysCount.add(count);
            } else {
                daysCount.add(0);
            }
        }
        return daysCount;
    }


    /**
     * 渠道转化统计
     *
     * @return
     */
    public JSONObject queryDataFromTransfer(BiParams biParams) {
        //查询时间的范围
        BiTimeUtil.BiTimeEntity biTimeEntity = BiTimeUtil.analyzeTime(biParams);
        //当前用户可查询对象，用来区分查询范围
        BiAuthority biAuthority = handleDataType(biParams);

        List<CrmDataFromTransfer> transferList = crmInstrumentMapper.queryDataFromTransfer(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity);
        List<CrmDataFromTransfer.RateData> rateDataList = new ArrayList<>();
        //设置饼状图数据及转化率数据
        for (int i = 0; i < transferList.size(); i++) {
            String rate = calculateRate(transferList.get(i).getDealCount(), transferList.get(i).getFormCount());
            transferList.get(i).setValue(rate.split("%")[0]);
//            transferList.get(i).setSort(i+1);
            CrmDataFromTransfer.RateData rateData = new CrmDataFromTransfer.RateData();
            rateData.setName(transferList.get(i).getName());
            rateData.setValue(rate.split("%")[0]);
            rateDataList.add(rateData);
        }

        Collections.sort(transferList, new Comparator<CrmDataFromTransfer>() {
            @Override
            public int compare(CrmDataFromTransfer o1, CrmDataFromTransfer o2) {
                if (new Double(o1.getValue()).compareTo(new Double(o2.getValue())) == 0) {
                    return -1;
                }
                return new Double(o2.getValue()).compareTo(new Double(o1.getValue()));
            }
        });

        /*for(int i=transferList.size()-1;i>=1;--i){
            for(int j=1;j<=i;j++ ){
                if(Double.valueOf(transferList.get(j-1).getValue()) < Double.valueOf(transferList.get(j).getValue())){
                    CrmDataFromTransfer currentJ = transferList.get(j);
                    CrmDataFromTransfer currentJ1 = transferList.get(j - 1);
                    transferList.remove(j);
                    transferList.add(j,currentJ1);
                    transferList.remove(j-1);
                    transferList.add(j-1,currentJ);
                }
            }
        }*/

        for (int i = 0; i < transferList.size(); i++) {
            transferList.get(i).setSort(i + 1);
            transferList.get(i).setValue(transferList.get(i).getValue() + "%");
        }


        Map<String, Object> transferMap = new HashMap<>();
        //设置表格数据信息
        transferMap.put("tableData", transferList);
        transferMap.put("rateData", rateDataList);
        return new JSONObject().fluentPut("transferData", transferMap);
    }

    /**
     * 查询销售部销售数据
     *
     * @param biParams
     * @return
     * @throws Exception
     */
    public SalesDepartmentDashBoardVO querySalesDepartmentSalesData(BiParams biParams) throws Exception {
        SalesDepartmentDashBoardVO dashBoardVO = new SalesDepartmentDashBoardVO();

        //查询时间的范围
        BiTimeUtil.BiTimeEntity biTimeEntity = BiTimeUtil.analyzeTime(biParams);
        //环比时间范围
        BiTimeUtil.BiTimeEntity momTimeRangeEntity = CrmInstrumentServiceImpl.moM(biParams.getType(), biParams.getStartTime(),
                biParams.getEndTime());
        //当前用户可查询对象，用来区分查询范围
        BiAuthority biAuthority = handleDataType(biParams);

        //限制范围内的线索总数
        Integer leadsCount = crmInstrumentMapper.queryLeadsCount(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams);

        //限制范围内的客户总数
        Integer customerCount = crmInstrumentMapper.queryCustomerCount(biAuthority.getUserIds(), biTimeEntity);

        //当前客户数
        CompletableFuture<Void> customer = CompletableFuture.runAsync(() -> {
            SalesDepartmentDashBoardVO.CustomerNum customerData = this.getSalesDepartmentCustomerData(biTimeEntity, momTimeRangeEntity,
                    biAuthority, customerCount, biParams.getDataForm());
            dashBoardVO.setCustomerNum(customerData);
        }, executor);

        //销售加微信数
        CompletableFuture<Void> salesAddWechat = CompletableFuture.runAsync(() -> {
            SalesDepartmentDashBoardVO.SalesAddWechatData salesAddWechatData = this.getSalesDepartmentAddWechatData(biTimeEntity,
                    momTimeRangeEntity, biAuthority, customerCount, biParams.getDataForm());
            dashBoardVO.setSalesAddWechatData(salesAddWechatData);
        }, executor);

        //进群客户数
        CompletableFuture<Void> customerJoinGroup = CompletableFuture.runAsync(() -> {
            SalesDepartmentDashBoardVO.CustomerJoinGroupData customerJoinGroupData = this.getSalesCustomerJoinGroupData(biTimeEntity,
                    momTimeRangeEntity, biAuthority, customerCount, biParams.getDataForm());
            dashBoardVO.setCustomerJoinGroupData(customerJoinGroupData);
        }, executor);

        //合同成交数
        CompletableFuture<Void> dealSuccessful = CompletableFuture.runAsync(() -> {
            SalesDepartmentDashBoardVO.DealSuccessfulData dealSuccessfulData = this.getSalesDealSuccessfulData(biTimeEntity,
                    momTimeRangeEntity, biAuthority, leadsCount, biParams.getDataForm());
            dashBoardVO.setDealSuccessfulData(dealSuccessfulData);
        }, executor);

        //合同金额
        CompletableFuture<Void> contractAmount = CompletableFuture.runAsync(() -> {
            SalesDepartmentDashBoardVO.ContractAmountData contractAmountData = this.getSalesContractAmountData(biTimeEntity,
                    momTimeRangeEntity, biAuthority, biParams.getDataForm());
            dashBoardVO.setContractAmountData(contractAmountData);
        }, executor);

        //回款金额
        CompletableFuture<Void> payBack = CompletableFuture.runAsync(() -> {
            SalesDepartmentDashBoardVO.PayBackData payBackData = this.getSalesPayBackData(biTimeEntity,
                    momTimeRangeEntity, biAuthority, biParams.getDataForm());
            dashBoardVO.setPayBackData(payBackData);
        }, executor);

        //合同金额 - 未回款
        CompletableFuture<Void> contractNotReceivablesAmount = CompletableFuture.runAsync(() -> {
            SalesDepartmentDashBoardVO.ContractNotReceivablesAmountData contractAmountData = this.getSalesContractNotReceivablesAmountData(biTimeEntity,
                    momTimeRangeEntity, biAuthority, biParams.getDataForm());
            dashBoardVO.setContractNotReceivablesAmountData(contractAmountData);
        }, executor);

        CompletableFuture.allOf(customer, salesAddWechat, customerJoinGroup, dealSuccessful, contractAmount, payBack, contractNotReceivablesAmount).exceptionally((e) -> {
            e.printStackTrace();
            return null;
        }).join();

        return dashBoardVO;
    }


    /**
     * 查询销售部仪表盘数据
     *
     * @param biParams
     * @return
     * @throws Exception
     */
    public SalesDepartmentDashBoardDataVO querySalesDepartmentDashboard(BiParams biParams) throws Exception {
        if(StringUtils.isEmpty(biParams.getDataForm())){
            biParams.setDataForm("涵品");
        }
        //查询时间的范围
        BiTimeUtil.BiTimeEntity biTimeEntity = BiTimeUtil.analyzeTime(biParams);
        //环比时间范围
        BiTimeUtil.BiTimeEntity momTimeRangeEntity = CrmInstrumentServiceImpl.moM(biParams.getType(), biParams.getStartTime(),
                biParams.getEndTime());
        //当前用户可查询对象，用来区分查询范围
        BiAuthority biAuthority = handleDataType(biParams);

        //总表单数   -- 线索总数
        Integer allFormCount = crmInstrumentMapper.queryAllFormCount(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams);
        //总线索数  -- 已报课线索数
        Integer leadsCount = 0;
        leadsCount = crmInstrumentMapper.querySignClassLeadsCount(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams);

        //客户数   -- 已转化客户数
        Integer customerCount = crmInstrumentMapper.queryLeadsCountForTransFor(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams);

        //合同成交数
        Integer dealContactCount = crmInstrumentMapper.queryDealContractCount(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams);

        //实际回款数
        BigDecimal receivablesMoney = crmInstrumentMapper.queryActualReceivablesSum(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams);

        // 退款金额
        BigDecimal refundMoney = crmInstrumentMapper.queryRefundMoney(biAuthority.getUserIds(),biTimeEntity,biParams);

        // 逾期/代偿金额
        BigDecimal overdueMoney = crmInstrumentMapper.queryOverdueMoney(biAuthority.getUserIds(),biTimeEntity,biParams);

        // 最终回款=实际回款-退款-逾期/代偿
        receivablesMoney = receivablesMoney.subtract(refundMoney).subtract(overdueMoney);

        //表单转化率
        String formTransRate = "0.00%";
        //线索转化率
        String leadsTransRate = "0.00%";
        //客户转化率
        String customerTransRate = "0.00%";

        String nowCustomerTransRate = "0.00%";
        //表单转化率
        if(dealContactCount.compareTo(Integer.valueOf(0)) <= 0 || allFormCount.compareTo(Integer.valueOf(0)) <= 0){
            formTransRate = "0.00%";
        }else{
            formTransRate = this.calculateRate(dealContactCount, allFormCount);
        }


        if(dealContactCount.compareTo(Integer.valueOf(0)) <= 0 || leadsCount.compareTo(Integer.valueOf(0)) <= 0){
            leadsTransRate = "0.00%";
        }else{
            leadsTransRate = this.calculateRate(dealContactCount, leadsCount);
        }

        //客户转化率
        if(customerCount.compareTo(Integer.valueOf(0)) <= 0 || dealContactCount.compareTo(Integer.valueOf(0)) <= 0){
            customerTransRate = "0.00%";
        }else{
            customerTransRate = this.calculateRate(dealContactCount, customerCount);
        }

        //客户成交率
//        String customerDealRate = this.calculateRate(dealContactCount, customerCount);
        if(customerCount.compareTo(Integer.valueOf(0)) <= 0 || allFormCount.compareTo(Integer.valueOf(0)) <= 0){
            nowCustomerTransRate = "0.00%";
        }else{
            nowCustomerTransRate = this.calculateRate(customerCount, allFormCount);
        }

        SalesDepartmentDashBoardDataVO vo = new SalesDepartmentDashBoardDataVO();

        SalesDepartmentDashBoardDataVO.CustomerNum customerNum = new SalesDepartmentDashBoardDataVO.CustomerNum();
        customerNum.setAllFormCount(allFormCount);
        customerNum.setLeadsCount(leadsCount);
        customerNum.setCustomerCount(customerCount);
        customerNum.setDealContactCount(dealContactCount);
        customerNum.setReceivablesMoney(receivablesMoney);
        vo.setCustomerNum(customerNum);

        SalesDepartmentDashBoardDataVO.FormTransRate formTransRateVo = new SalesDepartmentDashBoardDataVO.FormTransRate();
        formTransRateVo.setData(dealContactCount);
        formTransRateVo.setRate(formTransRate);
        formTransRateVo.setMom(0.00);
        formTransRateVo.setLabel("表单转化率");
        formTransRateVo.setTitle("表单转化率");
        formTransRateVo.setType("customer");
        formTransRateVo.setPlaTip("customerTip");
        formTransRateVo.setLabelValue(1);
        formTransRateVo.setSum(allFormCount);
        vo.setFormTransRate(formTransRateVo);


        SalesDepartmentDashBoardDataVO.LeadsTransRate leadsTransRateVo = new SalesDepartmentDashBoardDataVO.LeadsTransRate();
        leadsTransRateVo.setData(dealContactCount);
        leadsTransRateVo.setRate(leadsTransRate);
        leadsTransRateVo.setMom(0.00);
        leadsTransRateVo.setLabel("线索转化率");
        leadsTransRateVo.setTitle("线索转化率");
        leadsTransRateVo.setType("customer");
        leadsTransRateVo.setPlaTip("customerTip");
        leadsTransRateVo.setLabelValue(1);
        leadsTransRateVo.setSum(leadsCount);
        vo.setLeadsTransRate(leadsTransRateVo);

        SalesDepartmentDashBoardDataVO.CustomerTransRate customerTransRateVo = new SalesDepartmentDashBoardDataVO.CustomerTransRate();
        customerTransRateVo.setData(dealContactCount);
        customerTransRateVo.setRate(customerTransRate);
        customerTransRateVo.setMom(0.00);
        customerTransRateVo.setLabel("客户转化率");
        customerTransRateVo.setTitle("客户转化率");
        customerTransRateVo.setType("customer");
        customerTransRateVo.setPlaTip("customerTip");
        customerTransRateVo.setLabelValue(2);
        customerTransRateVo.setSum(customerCount);
        vo.setCustomerTransRate(customerTransRateVo);

        SalesDepartmentDashBoardDataVO.NowCustomerTransRate nowCustomerTransRateVo = new SalesDepartmentDashBoardDataVO.NowCustomerTransRate();
        nowCustomerTransRateVo.setData(customerCount);
        nowCustomerTransRateVo.setRate(nowCustomerTransRate);
        nowCustomerTransRateVo.setMom(0.00);
        nowCustomerTransRateVo.setLabel("当前客户转化率");
        nowCustomerTransRateVo.setTitle("当前客户转化率");
        nowCustomerTransRateVo.setType("customer");
        nowCustomerTransRateVo.setPlaTip("customerTip");
        nowCustomerTransRateVo.setLabelValue(2);
        nowCustomerTransRateVo.setSum(allFormCount);
        vo.setNowCustomerTransRate(nowCustomerTransRateVo);

        SalesDepartmentDashBoardDataVO.ContractDealRate contractDealRate = new SalesDepartmentDashBoardDataVO.ContractDealRate();
        contractDealRate.setData(dealContactCount);
        contractDealRate.setRate("0.00%");
        contractDealRate.setMom(0.00);
        contractDealRate.setLabel("合同成交数");
        contractDealRate.setTitle("合同成交数");
        contractDealRate.setType("contract");
        contractDealRate.setPlaTip("contractTip");
        contractDealRate.setLabelValue(6);
        vo.setContractDealRate(contractDealRate);

        SalesDepartmentDashBoardDataVO.ReceivablesMoneyRate receivablesMoneyRate = new SalesDepartmentDashBoardDataVO.ReceivablesMoneyRate();
        receivablesMoneyRate.setData(receivablesMoney);
        receivablesMoneyRate.setRate("0.00%");
        receivablesMoneyRate.setMom(0.00);
        receivablesMoneyRate.setLabel("实际回款金额");
        receivablesMoneyRate.setTitle("实际回款金额");
        receivablesMoneyRate.setType(" receivables");
        receivablesMoneyRate.setPlaTip(" receivablesTip");
        receivablesMoneyRate.setLabelValue(7);
        vo.setReceivablesMoneyRate(receivablesMoneyRate);

        return vo;
    }

    /**
     * 销售加微信数
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public SalesDepartmentDashBoardVO.SalesAddWechatData getSalesDepartmentAddWechatData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                                         BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                                         BiAuthority biAuthority,
                                                                                         Integer customerCount, String dataFrom) {

        Integer salesAddWechatCount = crmInstrumentMapper.querySalesAddWechatCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            Integer salesAddWechatCountMom = crmInstrumentMapper.querySalesAddWechatCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity);
            mom = calculateMom(salesAddWechatCount, salesAddWechatCountMom);
        }

        String rate = this.calculateRate(salesAddWechatCount, customerCount);

        SalesDepartmentDashBoardVO.SalesAddWechatData salesAddWechatData = new SalesDepartmentDashBoardVO.SalesAddWechatData();
        salesAddWechatData.setData(salesAddWechatCount);
        if (mom.indexOf("%") != -1) {
            salesAddWechatData.setMom(Double.valueOf(mom.split("%")[0]));
        } else {
            salesAddWechatData.setMom(0);
        }
        salesAddWechatData.setRate(rate);

        salesAddWechatData.setLabel("销售加微信");
        salesAddWechatData.setTitle("销售加微信");
        salesAddWechatData.setType("customer");
        salesAddWechatData.setPlaTip("customerTip");
        salesAddWechatData.setLabelValue(2);

        return salesAddWechatData;
    }

    public SalesDepartmentDashBoardVO.CustomerNum getSalesDepartmentCustomerData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                                 BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                                 BiAuthority biAuthority,
                                                                                 Integer customerCount, String dataFrom) {

        Integer queryDealCustomerCount = crmInstrumentMapper.queryDealCustomerCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);
        Integer queryNotDealCustomerCount = crmInstrumentMapper.queryNotDealCustomerCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        SalesDepartmentDashBoardVO.CustomerNum customerData = new SalesDepartmentDashBoardVO.CustomerNum();
        customerData.setData(customerCount);
        customerData.setDealCustomer(queryDealCustomerCount == null ? 0 : queryDealCustomerCount);
        customerData.setNotDealCustomer(queryNotDealCustomerCount == null ? 0 : queryNotDealCustomerCount);

        return customerData;
    }

    /**
     * 进群客户数
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public SalesDepartmentDashBoardVO.CustomerJoinGroupData getSalesCustomerJoinGroupData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                                          BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                                          BiAuthority biAuthority,
                                                                                          Integer customerCount, String dataFrom) {

        Integer customerJoinGroupCount = crmInstrumentMapper.queryCustomerJoinGroupCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            Integer customerJoinGroupCountMom = crmInstrumentMapper.queryCustomerJoinGroupCount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity);
            mom = calculateMom(customerJoinGroupCount, customerJoinGroupCountMom);
        }

        String rate = this.calculateRate(customerJoinGroupCount, customerCount);

        SalesDepartmentDashBoardVO.CustomerJoinGroupData customerJoinGroupData = new SalesDepartmentDashBoardVO.CustomerJoinGroupData();
        customerJoinGroupData.setData(customerJoinGroupCount);
        if (mom.indexOf("%") != -1) {
            customerJoinGroupData.setMom(Double.valueOf(mom.split("%")[0]));
        } else {
            customerJoinGroupData.setMom(0);
        }
        customerJoinGroupData.setRate(rate);

        customerJoinGroupData.setLabel("客户进群");
        customerJoinGroupData.setTitle("客户进群");
        customerJoinGroupData.setType("customer");
        customerJoinGroupData.setPlaTip("customerTip");
        customerJoinGroupData.setLabelValue(2);

        return customerJoinGroupData;
    }

    /**
     * 成交合同数 - 20210521修改逻辑：有效合同数/全部客户数 queryCustomerNumByData
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public SalesDepartmentDashBoardVO.DealSuccessfulData getSalesDealSuccessfulData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                                    BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                                    BiAuthority biAuthority,
                                                                                    Integer customerCount, String dataFrom) {

        Integer contractCountMom = crmInstrumentMapper.queryContractCount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);
        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {

            mom = calculateMom(contractCountMom, customerCount);
        }

        String rate = this.calculateRate(contractCountMom, customerCount);

        SalesDepartmentDashBoardVO.DealSuccessfulData dealSuccessfulData = new SalesDepartmentDashBoardVO.DealSuccessfulData();
        dealSuccessfulData.setData(contractCountMom);
        if (mom.indexOf("%") != -1) {
            dealSuccessfulData.setMom(Double.valueOf(mom.split("%")[0]));
        } else {
            dealSuccessfulData.setMom(0);
        }
        dealSuccessfulData.setRate(rate);

        dealSuccessfulData.setLabel("成交合同数");
        dealSuccessfulData.setTitle("成交合同数");
        dealSuccessfulData.setType("contract");
        dealSuccessfulData.setPlaTip("contractTip");
        dealSuccessfulData.setLabelValue(6);

        return dealSuccessfulData;
    }

    /**
     * 合同金额
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public SalesDepartmentDashBoardVO.ContractAmountData getSalesContractAmountData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                                    BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                                    BiAuthority biAuthority, String dataFrom) {

        BigDecimal contractAmount = crmInstrumentMapper.queryContractAmount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            BigDecimal contractAmountMom = crmInstrumentMapper.queryContractAmount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity);
            mom = calculateMom(contractAmount, contractAmountMom);
        }

        //实付金额
        BigDecimal payed = crmInstrumentMapper.queryContractPayed(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String rate = this.calculateRate(contractAmount, payed);

        SalesDepartmentDashBoardVO.ContractAmountData contractAmountData = new SalesDepartmentDashBoardVO.ContractAmountData();
        contractAmountData.setData(contractAmount);
        if (mom.indexOf("%") != -1) {
            contractAmountData.setMom(Double.valueOf(mom.split("%")[0]));
        } else {
            contractAmountData.setMom(0);
        }
        contractAmountData.setRate(rate);

        contractAmountData.setLabel("合同金额");
        contractAmountData.setTitle("合同金额");
        contractAmountData.setType("contract");
        contractAmountData.setPlaTip("contract");
        contractAmountData.setLabelValue(6);

        return contractAmountData;
    }

    /**
     * 合同金额-未回款金额
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public SalesDepartmentDashBoardVO.ContractNotReceivablesAmountData getSalesContractNotReceivablesAmountData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                                                                BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                                                                BiAuthority biAuthority, String dataFrom) {

        BigDecimal contractAmount = crmInstrumentMapper.queryContractNotReceivablesAmount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            BigDecimal contractAmountMom = crmInstrumentMapper.queryContractAmount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity);
            mom = calculateMom(contractAmount, contractAmountMom);
        }

        //实付金额
        BigDecimal payed = crmInstrumentMapper.queryContractPayed(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String rate = this.calculateRate(contractAmount, payed);

        SalesDepartmentDashBoardVO.ContractNotReceivablesAmountData contractAmountData = new SalesDepartmentDashBoardVO.ContractNotReceivablesAmountData();
        contractAmountData.setData(contractAmount);

        contractAmountData.setMom("--");
        contractAmountData.setRate("--");

        contractAmountData.setLabel("合同金额");
        contractAmountData.setTitle("合同金额");
        contractAmountData.setType("contract");
        contractAmountData.setPlaTip("contract");
        contractAmountData.setLabelValue(6);

        return contractAmountData;
    }

    /**
     * 回款金额
     *
     * @param timeRangeEntity
     * @param momTimeRangeEntity
     * @param biAuthority
     * @return
     */
    public SalesDepartmentDashBoardVO.PayBackData getSalesPayBackData(BiTimeUtil.BiTimeEntity timeRangeEntity,
                                                                      BiTimeUtil.BiTimeEntity momTimeRangeEntity,
                                                                      BiAuthority biAuthority, String dataFrom) {

        BigDecimal payBackAmount = crmInstrumentMapper.queryPayBackAmount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String mom = "时间范围为全部时，没有环比";
        if (!timeRangeEntity.getIsSelectAll()) {
            BigDecimal payBackAmountMom = crmInstrumentMapper.queryPayBackAmount(dataFrom, biAuthority.getUserIds(), momTimeRangeEntity);
            mom = calculateMom(payBackAmount, payBackAmountMom);
        }

        //应回款金额
        BigDecimal payed = crmInstrumentMapper.queryPayedBackAmount(dataFrom, biAuthority.getUserIds(), timeRangeEntity);

        String rate = this.calculateRate(payBackAmount, payed);

        SalesDepartmentDashBoardVO.PayBackData payBackData = new SalesDepartmentDashBoardVO.PayBackData();
        payBackData.setData(payBackAmount);
        if (mom.indexOf("%") != -1) {
            payBackData.setMom(Double.valueOf(mom.split("%")[0]));
        } else {
            payBackData.setMom(0);
        }
        payBackData.setRate(rate);

        payBackData.setLabel("回款金额");
        payBackData.setTitle("回款金额");
        payBackData.setType("receivables");
        payBackData.setPlaTip("receivables");
        payBackData.setLabelValue(7);

        return payBackData;
    }

    /**
     * 查询每日成交数量
     *
     * @param biParams
     * @return
     */
    public JSONObject queryDaysDealCount(BiParams biParams) {
        if(StringUtils.isBlank(biParams.getDataForm())){
            biParams.setDataForm("涵品");
        }
        BiAuthority biAuthority = handleDataType(biParams);
        //获取15天内的日期
        List<String> daysList = getDays(15);
        List<Integer> dataList = new ArrayList<>();
        for (int i = 0; i < daysList.size(); i++) {
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("createTime", daysList.get(i));
            dataMap.put("ownerUserIds", biAuthority.getUserIds());
            if(!StringUtils.isEmpty(biParams.getRepetition())){
                dataMap.put("repetition", biParams.getRepetition());
            }
            if(!StringUtils.isEmpty(biParams.getPeriods())){
                dataMap.put("periods", biParams.getPeriods());
            }
            if(Optional.ofNullable(biParams.getCategories()).isPresent()){
                dataMap.put("categories", biParams.getCategories());
            }
            if(Optional.ofNullable(biParams.getSalesType()).isPresent()){
                dataMap.put("salesType", biParams.getSalesType());
            }
            if(!StringUtils.isEmpty(biParams.getDataForm())){
                dataMap.put("dataFrom", biParams.getDataForm());
            }
            Integer dataCount = crmInstrumentMapper.queryDaysDealCount(dataMap);
            dataList.add(dataCount);
        }

        Map<String, Object> dataListMap = new HashMap<>();
        //设置表格数据信息
        dataListMap.put("xData", daysList);
        dataListMap.put("yData", dataList);
        return new JSONObject().fluentPut("DealCount", dataListMap);

    }

    /**
     * 教学部仪表盘销售数据
     *
     * @param biParams
     * @return
     */
    public TeachingDepartmentDashBoardVO queryTeachingDepartmentData(BiParams biParams) {
        TeachingDepartmentDashBoardVO dashBoardVO = new TeachingDepartmentDashBoardVO();

        //查询时间的范围
        BiTimeUtil.BiTimeEntity biTimeEntity = BiTimeUtil.analyzeTime(biParams);
        //当前用户可查询对象，用来区分查询范围
        BiAuthority biAuthority = handleDataType(biParams);

        //拼装查询条件
        Map<String, Object> contactsCountMap = new HashMap<>();
        contactsCountMap.put("ownerUserIds", biAuthority.getUserIds());
        contactsCountMap.put("vipPeriods", biParams.getVipPeriods());
        contactsCountMap.put("contactsType", biParams.getContactsType());

        //联系人总数
        Integer contactsCount = crmInstrumentMapper.queryContactsData(contactsCountMap, biTimeEntity);

        //休学人数
        Integer xiuXue = crmInstrumentMapper.queryXiuXueContactsData(contactsCountMap);

        //当期人数
        Integer currentContacts;
        //转期
        Integer zhuanqi = 0;
        //重修
        Integer chongxiu = 0;
        if (StringUtils.isEmpty(biParams.getVipPeriods())) {

            //是否转期等于是
            zhuanqi = crmInstrumentMapper.queryZhuanQiuData(contactsCountMap);
            //是否重修等于是
            chongxiu = crmInstrumentMapper.queryChongXiuData(contactsCountMap);
            //VIP期数为空时，当期人数 = 报名人数 - 休学 + 重修
            currentContacts = contactsCount - xiuXue + zhuanqi + chongxiu;
        } else {
            chongxiu = crmInstrumentMapper.queryChongXiuQianData(contactsCountMap);
            zhuanqi = crmInstrumentMapper.queryZhuanQiQianData(contactsCountMap);
            currentContacts = contactsCount - xiuXue + zhuanqi + chongxiu;
        }
        //VIP报名数量
        CompletableFuture<Void> vipNumber = CompletableFuture.runAsync(() -> {
            //根据VIP期数获取训练营期数并查询客户信息
            Integer customerCount = crmInstrumentMapper.queryCustomerCountByData(contactsCountMap, biTimeEntity);

            String rate = this.calculateRate(contactsCount, customerCount);

            TeachingDepartmentDashBoardVO.VipApplicationsNumber vipApplicationsNumber = new TeachingDepartmentDashBoardVO.VipApplicationsNumber();
            vipApplicationsNumber.setData(contactsCount);
            vipApplicationsNumber.setRate(rate);

            vipApplicationsNumber.setLabel("VIP报名数");
            vipApplicationsNumber.setTitle("VIP报名数");
            vipApplicationsNumber.setType("contacts");
            vipApplicationsNumber.setPlaTip("contactsTip");
            vipApplicationsNumber.setLabelValue(3);

            dashBoardVO.setVipApplicationsNumber(vipApplicationsNumber);
        }, executor);

        //复购
        CompletableFuture<Void> afterPurchase = CompletableFuture.runAsync(() -> {
            Map<String, Object> fuGouMap = new HashMap<>();
            fuGouMap.put("ownerUserIds", biAuthority.getUserIds());
            fuGouMap.put("vipPeriods", biParams.getVipPeriods());
            fuGouMap.put("contactsType", biParams.getContactsType());
            fuGouMap.put("afterPurchase", "是");
            Integer fuGouCount = crmInstrumentMapper.queryDifferentDataCountByData(fuGouMap, biTimeEntity);

            String rate = this.calculateRate(fuGouCount, currentContacts);
            TeachingDepartmentDashBoardVO.AfterPurchase purchase = new TeachingDepartmentDashBoardVO.AfterPurchase();
            purchase.setData(fuGouCount);
            purchase.setRate(rate);

            purchase.setLabel("复购人数");
            purchase.setTitle("复购人数");
            purchase.setType("contacts");
            purchase.setPlaTip("contactsTip");
            purchase.setLabelValue(3);

            dashBoardVO.setAfterPurchaseCount(purchase);
        }, executor);

        //转期
        Integer finalZhuanqi = zhuanqi;
        CompletableFuture<Void> refundingCount = CompletableFuture.runAsync(() -> {
            String rate = this.calculateRate(finalZhuanqi, currentContacts);
            TeachingDepartmentDashBoardVO.Refunding refunding = new TeachingDepartmentDashBoardVO.Refunding();
            refunding.setData(finalZhuanqi);
            refunding.setRate(rate);

            refunding.setLabel("转期人数");
            refunding.setTitle("转期人数");
            refunding.setType("contacts");
            refunding.setPlaTip("contactsTip");
            refunding.setLabelValue(3);

            dashBoardVO.setRefundingCount(refunding);
        }, executor);

        //休学
        CompletableFuture<Void> suspensionSchoolingCount = CompletableFuture.runAsync(() -> {
            String rate = this.calculateRate(xiuXue, currentContacts);
            TeachingDepartmentDashBoardVO.SuspensionSchooling schooling = new TeachingDepartmentDashBoardVO.SuspensionSchooling();
            schooling.setData(xiuXue);
            schooling.setRate(rate);

            schooling.setLabel("休学人数");
            schooling.setTitle("休学人数");
            schooling.setType("contacts");
            schooling.setPlaTip("contactsTip");
            schooling.setLabelValue(3);

            dashBoardVO.setSuspensionSchoolingCount(schooling);
        }, executor);

        //重修
        Integer finalChongxiu = chongxiu;
        CompletableFuture<Void> relearnCount = CompletableFuture.runAsync(() -> {
            String rate = this.calculateRate(finalChongxiu, currentContacts);
            TeachingDepartmentDashBoardVO.RelearnData relearnData = new TeachingDepartmentDashBoardVO.RelearnData();
            relearnData.setData(finalChongxiu);
            relearnData.setRate(rate);

            relearnData.setLabel("重修人数");
            relearnData.setTitle("重修人数");
            relearnData.setType("contacts");
            relearnData.setPlaTip("contactsTip");
            relearnData.setLabelValue(3);

            dashBoardVO.setRelearnCount(relearnData);
        }, executor);

        //定稿
        CompletableFuture<Void> finalizedCount = CompletableFuture.runAsync(() -> {
            Map<String, Object> finalizedMap = new HashMap<>();
            finalizedMap.put("ownerUserIds", biAuthority.getUserIds());
            finalizedMap.put("vipPeriods", biParams.getVipPeriods());
            finalizedMap.put("contactsType", biParams.getContactsType());
            finalizedMap.put("finalized", "是");
            Integer finalized = crmInstrumentMapper.queryDifferentDataCountByData(finalizedMap, biTimeEntity);

            String rate = this.calculateRate(finalized, currentContacts);
            TeachingDepartmentDashBoardVO.Finalized finalizedData = new TeachingDepartmentDashBoardVO.Finalized();
            finalizedData.setData(finalized);
            finalizedData.setRate(rate);

            finalizedData.setLabel("定稿人数");
            finalizedData.setTitle("定稿人数");
            finalizedData.setType("contacts");
            finalizedData.setPlaTip("contactsTip");
            finalizedData.setLabelValue(3);

            dashBoardVO.setFinalizedCount(finalizedData);
        }, executor);

        //派单
        CompletableFuture<Void> sendSingleNumSum = CompletableFuture.runAsync(() -> {
            Map<String, Object> sendSingle = new HashMap<>();
            sendSingle.put("ownerUserIds", biAuthority.getUserIds());
            sendSingle.put("vipPeriods", biParams.getVipPeriods());
            sendSingle.put("contactsType", biParams.getContactsType());
            Integer sendSingleNum = crmInstrumentMapper.querySendSingleNumCount(sendSingle, biTimeEntity);
            Integer finalizedNum = crmInstrumentMapper.queryFinalizedNumCount(sendSingle, biTimeEntity);

            String rate = this.calculateRate(finalizedNum, sendSingleNum);
            TeachingDepartmentDashBoardVO.SendSingleNum singleNum = new TeachingDepartmentDashBoardVO.SendSingleNum();
            singleNum.setData(sendSingleNum);
            singleNum.setDealData(finalizedNum);
            singleNum.setRate(rate);

            singleNum.setLabel("总派单数");
            singleNum.setTitle("总派单数");
            singleNum.setType("contacts");
            singleNum.setPlaTip("contactsTip");
            singleNum.setLabelValue(3);

            dashBoardVO.setSendSingleNum(singleNum);
        }, executor);

        //VIP最终人数
        CompletableFuture<Void> vipFinalNumberCount = CompletableFuture.runAsync(() -> {
            //根据VIP期数获取训练营期数并查询客户信息

            String rate = this.calculateRate(currentContacts, contactsCount);

            TeachingDepartmentDashBoardVO.VipFinalNumber vipFinalNumber = new TeachingDepartmentDashBoardVO.VipFinalNumber();
            vipFinalNumber.setData(currentContacts);
            vipFinalNumber.setRate(rate);

            vipFinalNumber.setLabel("VIP最终人数");
            vipFinalNumber.setTitle("VIP最终人数");
            vipFinalNumber.setType("contacts");
            vipFinalNumber.setPlaTip("contactsTip");
            vipFinalNumber.setLabelValue(3);

            dashBoardVO.setVipFinalNumber(vipFinalNumber);
        }, executor);

        CompletableFuture.allOf(vipNumber, afterPurchase, refundingCount, suspensionSchoolingCount, relearnCount, finalizedCount, sendSingleNumSum, vipFinalNumberCount).exceptionally((e) -> {
            e.printStackTrace();
            return null;
        }).join();

        return dashBoardVO;
    }

    public List<CrmContactsInstrumentTableData> queryTeachingDepartmentTableData(BiParams biParams) {
        //查询时间的范围
        BiTimeUtil.BiTimeEntity biTimeEntity = BiTimeUtil.analyzeTime(biParams);
        //当前用户可查询对象，用来区分查询范围
        BiAuthority biAuthority = handleDataType(biParams);

        //拼装查询条件
        Map<String, Object> contactsCountMap = new HashMap<>();
        contactsCountMap.put("ownerUserIds", biAuthority.getUserIds());
        contactsCountMap.put("vipPeriods", biParams.getVipPeriods());
        contactsCountMap.put("contactsType", biParams.getContactsType());
        return crmInstrumentMapper.queryContactsTableData(contactsCountMap);
    }

    public SalesDepartmentDashBoardDataVO queryStatDataForClassData(BiParams biParams) throws Exception {
        if(StringUtils.isEmpty(biParams.getDataForm())){
            biParams.setDataForm("涵品");
        }
        //查询时间的范围
        BiTimeUtil.BiTimeEntity biTimeEntity = BiTimeUtil.analyzeTime(biParams);
        //当前用户可查询对象，用来区分查询范围
        BiAuthority biAuthority = handleDataType(biParams);
//        List<Long> userIdList = SpringUtils.getBean(AdminService.class).queryUserIdsByRoleIds().getData();

        String dateToString = "";
        if(ObjectUtil.isNotEmpty(biParams.getClassId())){
            Map<String, Object> map = (Map<String, Object>) SpringUtils.getBean(CrmService.class).queryTimeTableDataById(biParams.getClassId());
            dateToString = String.valueOf(map.get("classTime")).split("-")[0]+ String.valueOf(map.get("classTime")).split("-")[1];
        }else{
            biParams.setClassId(0);
            dateToString = DateUtil.format(new Date(),"yyyyMM");
        }

        //获取讲师集合
        Integer classId = biParams.getClassId();
        List<Long> teacherIdList = this.crmInstrumentMapper.queryTeacherByClassData(classId);
        //获取所有训练营期数
        List<String> trainingPeriodsByClassData = this.crmInstrumentMapper.queryTrainingPeriodsByClassData(biParams.getClassId());
        List<String> trainingPeriodsList = new ArrayList<>();

        for(String trainingPeriods : trainingPeriodsByClassData){
            List<String> tempList = Arrays.asList(trainingPeriods.split(","));
            trainingPeriodsList.addAll(tempList);
        }

        trainingPeriodsList = new ArrayList<String>(new TreeSet<String>(trainingPeriodsList));

        List<CrmTimeTableData> classDataList = this.crmInstrumentMapper.queryTimeTableDataByClassId(classId);
        for(CrmTimeTableData crmTimeTableData : classDataList){
            crmTimeTableData.setTrainingPeriodList(Arrays.asList(crmTimeTableData.getTrainingPeriods().split(",")));
        }

        Integer allFormCount = 0;
        Integer customerCount = 0;
        Integer dealContactCount = 0;
        Integer customerCountForPeriods = 0;
        Integer allFormCountForPeriods = 0;
        Integer leadsCountForPeriods = 0;
        if(ObjectUtil.isNotEmpty(biParams.getClassId())){
            //总表单数   -- 线索总数
            allFormCount = crmInstrumentMapper.queryAllFormCountForClassData(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams,classDataList);

            //客户数   -- 已转化客户数
            customerCount = crmInstrumentMapper.queryLeadsCountForTransForForClassData(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams,classDataList);

            //合同成交数
            dealContactCount = crmInstrumentMapper.queryDealContractCount(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams);

            // 根据课程排期获取客户数
            if(ObjectUtil.isNotEmpty(biParams.getStartTime()) && ObjectUtil.isNotEmpty(biParams.getEndTime())){
                customerCountForPeriods = crmInstrumentMapper.queryLeadsCountForTransForPeriodsForClass(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams,classDataList);
            }else{
                customerCountForPeriods = crmInstrumentMapper.queryLeadsCountForTransForPeriodsForClassNoTime(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams,classDataList);
            }

            //根据课程排期获取总表单数
            if(ObjectUtil.isNotEmpty(biParams.getStartTime()) && ObjectUtil.isNotEmpty(biParams.getEndTime())){
                allFormCountForPeriods = crmInstrumentMapper.queryAllFormCountForPeriodsForClass(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams,classDataList);
            }else{
                allFormCountForPeriods = crmInstrumentMapper.queryAllFormCountForPeriodsForClassNoTime(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams,classDataList);
            }

            //根据课程排期获取总线索数
            if(ObjectUtil.isNotEmpty(biParams.getStartTime()) && ObjectUtil.isNotEmpty(biParams.getEndTime())){
                leadsCountForPeriods = crmInstrumentMapper.querySignClassLeadsCountForPeriodsForClass(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams,classDataList);
            }else{
                leadsCountForPeriods = crmInstrumentMapper.querySignClassLeadsCountForPeriodsForClassNoTime(biParams.getDataForm(), biAuthority.getUserIds(), biTimeEntity, biParams,classDataList);
            }
        }


        //表单转化率
        String formTransRate = "0.00%";
        //线索转化率
        String leadsTransRate = "0.00%";
        //客户转化率
        String customerTransRate = "0.00%";

        String nowCustomerTransRate = "0.00%";
        //表单转化率
        if(dealContactCount.compareTo(Integer.valueOf(0)) <= 0 || allFormCountForPeriods.compareTo(Integer.valueOf(0)) <= 0){
            formTransRate = "0.00%";
        }else{
            formTransRate = this.calculateRate(dealContactCount, allFormCountForPeriods);
        }


        if(dealContactCount.compareTo(Integer.valueOf(0)) <= 0 || leadsCountForPeriods.compareTo(Integer.valueOf(0)) <= 0){
            leadsTransRate = "0.00%";
        }else{
            leadsTransRate = this.calculateRate(dealContactCount, leadsCountForPeriods);
        }

        //客户转化率
        if(dealContactCount.compareTo(Integer.valueOf(0)) <= 0 || customerCount.compareTo(Integer.valueOf(0)) <= 0){
            customerTransRate = "0.00%";
        }else{
            customerTransRate = this.calculateRate(dealContactCount, customerCount);
        }

        //客户成交率
//        String customerDealRate = this.calculateRate(dealContactCount, customerCount);
        if(customerCount.compareTo(Integer.valueOf(0)) <= 0 || allFormCount.compareTo(Integer.valueOf(0)) <= 0){
            nowCustomerTransRate = "0.00%";
        }else{
            nowCustomerTransRate = this.calculateRate(customerCount, allFormCount);
        }

        SalesDepartmentDashBoardDataVO vo = new SalesDepartmentDashBoardDataVO();

        SalesDepartmentDashBoardDataVO.FormTransRate formTransRateVo = new SalesDepartmentDashBoardDataVO.FormTransRate();
        if(ObjectUtil.isNotEmpty(biParams.getClassId())){
            formTransRateVo.setData(dealContactCount);
            formTransRateVo.setRate(formTransRate);
            formTransRateVo.setMom(0.00);
            formTransRateVo.setLabel("表单转化率");
            formTransRateVo.setTitle("表单转化率");
            formTransRateVo.setType("customer");
            formTransRateVo.setPlaTip("customerTip");
            formTransRateVo.setLabelValue(1);
            formTransRateVo.setSum(allFormCountForPeriods);
            vo.setFormTransRate(formTransRateVo);
        }


        SalesDepartmentDashBoardDataVO.LeadsTransRate leadsTransRateVo = new SalesDepartmentDashBoardDataVO.LeadsTransRate();
        if(ObjectUtil.isNotEmpty(biParams.getClassId())){
            leadsTransRateVo.setData(dealContactCount);
            leadsTransRateVo.setRate(leadsTransRate);
            leadsTransRateVo.setMom(0.00);
            leadsTransRateVo.setLabel("线索转化率");
            leadsTransRateVo.setTitle("线索转化率");
            leadsTransRateVo.setType("customer");
            leadsTransRateVo.setPlaTip("customerTip");
            leadsTransRateVo.setLabelValue(1);
            leadsTransRateVo.setSum(leadsCountForPeriods);
            vo.setLeadsTransRate(leadsTransRateVo);
        }

        SalesDepartmentDashBoardDataVO.CustomerTransRate customerTransRateVo = new SalesDepartmentDashBoardDataVO.CustomerTransRate();
        if(ObjectUtil.isNotEmpty(biParams.getClassId())){
            customerTransRateVo.setData(dealContactCount);
            customerTransRateVo.setRate(customerTransRate);
            customerTransRateVo.setMom(0.00);
            customerTransRateVo.setLabel("客户转化率");
            customerTransRateVo.setTitle("客户转化率");
            customerTransRateVo.setType("customer");
            customerTransRateVo.setPlaTip("customerTip");
            customerTransRateVo.setLabelValue(2);
            customerTransRateVo.setSum(customerCount);
            vo.setCustomerTransRate(customerTransRateVo);
        }

        SalesDepartmentDashBoardDataVO.NowCustomerTransRate nowCustomerTransRateVo = new SalesDepartmentDashBoardDataVO.NowCustomerTransRate();
        if(ObjectUtil.isNotEmpty(biParams.getClassId())){
            nowCustomerTransRateVo.setData(customerCount);
            nowCustomerTransRateVo.setRate(nowCustomerTransRate);
            nowCustomerTransRateVo.setMom(0.00);
            nowCustomerTransRateVo.setLabel("当前客户转化率");
            nowCustomerTransRateVo.setTitle("当前客户转化率");
            nowCustomerTransRateVo.setType("customer");
            nowCustomerTransRateVo.setPlaTip("customerTip");
            nowCustomerTransRateVo.setLabelValue(2);
            nowCustomerTransRateVo.setSum(allFormCount);
            vo.setNowCustomerTransRate(nowCustomerTransRateVo);
        }


        return vo;
    }

    /**
     * 线索总数
     * @param biParams
     * @return
     */
    public Map<String,Object> leadsStatis(BiParams biParams){
        if(!Optional.ofNullable(biParams.getStatisType()).isPresent()){
            biParams.setStatisType(CrmBusinessEnum.PublicEnum.ONE.getType());
        }
        if(!CrmBusinessEnum.PublicEnum.ONE.getType().equals(biParams.getStatisType())
                && !CrmBusinessEnum.PublicEnum.TWO.getType().equals(biParams.getStatisType())){
            biParams.setStatisType(CrmBusinessEnum.PublicEnum.ONE.getType());
        }
        List<Long> userIdList = buildUserList(biParams);
        log.info("线索总数  loginUser:"+UserUtil.getUser().getRealname()+",userIdList:"+JSONObject.toJSONString(userIdList));
        if(CollectionUtil.isEmpty(userIdList)){
            Map<String,Object> result = new HashMap<>();
            result.put("leadsNum",0);
            result.put("leadsNumNOTransform",0);
            result.put("leadsNumTransform",0);
            return result;
        }

        Integer statisType = biParams.getStatisType();
        Integer leadsNum = crmInstrumentMapper.getLeadsNum(userIdList, biParams.getStartTime(),biParams.getEndTime(),statisType);
        Integer leadsNumNOTransform = crmInstrumentMapper.getLeadsNumNOTransform(userIdList, biParams.getStartTime(),biParams.getEndTime(),statisType);
        Integer leadsNumTransform = crmInstrumentMapper.getLeadsNumTransform(userIdList, biParams.getStartTime(),biParams.getEndTime(),statisType);
        Map<String,Object> result = new HashMap<>();
        result.put("leadsNum",leadsNum);
        result.put("leadsNumNOTransform",leadsNumNOTransform);
        result.put("leadsNumTransform",leadsNumTransform);
        return result;
    }

    /**
     * 总数统计
     * @param biParams
     * @return
     */
    public Map<String,Object> numStatis(BiParams biParams){
        if(!Optional.ofNullable(biParams.getStatisType()).isPresent()){
            biParams.setStatisType(CrmBusinessEnum.PublicEnum.ONE.getType());
        }
        if(!CrmBusinessEnum.PublicEnum.ONE.getType().equals(biParams.getStatisType())
                && !CrmBusinessEnum.PublicEnum.TWO.getType().equals(biParams.getStatisType())){
            biParams.setStatisType(CrmBusinessEnum.PublicEnum.ONE.getType());
        }
        List<Long> userIdList = buildUserList(biParams);
        log.info("总数统计  loginUser:"+UserUtil.getUser().getRealname()+",userIdList:"+JSONObject.toJSONString(userIdList));
        if(CollectionUtil.isEmpty(userIdList)){
            Map<String,Object> result = new HashMap<>();
            result.put("studentNum",0);
            result.put("vipStudentNum",0);
            result.put("contractNum",0);
            return result;
        }

        Map<String,Object> result = new HashMap<>();

        List<Long> finalUserIdList = userIdList;
        Integer statisType = biParams.getStatisType();
        CompletableFuture<Void> studentNumFuture = CompletableFuture.runAsync(() -> {
            //学员总数
            Integer studentNum = crmInstrumentMapper.getStudentNum(finalUserIdList, biParams.getStartTime(),biParams.getEndTime(),statisType);
            result.put("studentNum",studentNum);
        }, executor);

        CompletableFuture<Void> vipStudentNumFuture = CompletableFuture.runAsync(() -> {
            //vip学员总数
            Integer vipStudentNum = crmInstrumentMapper.getVipStudentNum(finalUserIdList, biParams.getStartTime(),biParams.getEndTime(),statisType);
            result.put("vipStudentNum",vipStudentNum);
        }, executor);

        CompletableFuture<Void> contractNumFuture = CompletableFuture.runAsync(() -> {
            //合同总数
            if(CrmBusinessEnum.PublicEnum.ONE.getType().equals(biParams.getStatisType())){
                Integer contractNum = crmInstrumentMapper.getContractNum(finalUserIdList, biParams.getStartTime(),biParams.getEndTime(),statisType);
                result.put("contractNum",contractNum);
            }else{
                result.put("contractNum",0);
            }

        }, executor);

        CompletableFuture.allOf(studentNumFuture, vipStudentNumFuture, contractNumFuture).exceptionally((e) -> {
            e.printStackTrace();
            return null;
        }).join();

        return result;
    }

    /**
     * 金额统计
     * @param biParams
     * @return
     */
    public Map<String,Object> moneyStatis(BiParams biParams){
        if(!Optional.ofNullable(biParams.getStatisType()).isPresent()){
            biParams.setStatisType(CrmBusinessEnum.PublicEnum.ONE.getType());
        }
        if(!CrmBusinessEnum.PublicEnum.ONE.getType().equals(biParams.getStatisType())
                && !CrmBusinessEnum.PublicEnum.TWO.getType().equals(biParams.getStatisType())){
            biParams.setStatisType(CrmBusinessEnum.PublicEnum.ONE.getType());
        }
        List<Long> userIdList = buildUserList(biParams);
        log.info("金额统计  loginUser:"+UserUtil.getUser().getRealname()+",userIdList:"+JSONObject.toJSONString(userIdList));
        if(CollectionUtil.isEmpty(userIdList)){
            String money = "0.00";
            Map<String,Object> result = new HashMap<>();
            result.put("contractMoney",money);
            result.put("orderMoney",money);
            result.put("receivablesMoney",money);
            result.put("firstReceivablesMoney",money);
            result.put("offlineMoney",money);// 线下补款
            result.put("refundMoney",money);
            return result;
        }

        Map<String,Object> result = new HashMap<>();

        List<Long> finalUserIdList = userIdList;
        CompletableFuture<Void> contractMoneyFuture = CompletableFuture.runAsync(() -> {
            //合同金额
            BigDecimal contractMoney = crmInstrumentMapper.getContractMoney(finalUserIdList, biParams.getStartTime(),biParams.getEndTime());
            result.put("contractMoney",contractMoney.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString());
        }, executor);

        CompletableFuture<Void> orderMoneyFuture = CompletableFuture.runAsync(() -> {
            //账单回款金额
            BigDecimal orderMoney = crmInstrumentMapper.getOrderMoney(finalUserIdList, biParams.getStartTime(),biParams.getEndTime());
            result.put("orderMoney",orderMoney.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString());
        }, executor);

        CompletableFuture<Void> receivablesMoneyFuture = CompletableFuture.runAsync(() -> {
            //现金回款金额
            BigDecimal receivablesMoney = crmInstrumentMapper.getReceivablesMoney(finalUserIdList, biParams.getStartTime(),biParams.getEndTime());
            result.put("receivablesMoney",receivablesMoney.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString());
        }, executor);

        CompletableFuture<Void> firstReceivablesMoneyFuture = CompletableFuture.runAsync(() -> {
            //首付款回款金额
            BigDecimal firstReceivablesMoney = crmInstrumentMapper.getFirstReceivablesMoney(finalUserIdList, biParams.getStartTime(),biParams.getEndTime());
            result.put("firstReceivablesMoney",firstReceivablesMoney.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString());
        }, executor);

        CompletableFuture<Void> offlineMoneyFuture = CompletableFuture.runAsync(() -> {
            //线下补款金额
            BigDecimal offlineMoney = crmInstrumentMapper.getOfflineMoney(finalUserIdList, biParams.getStartTime(),biParams.getEndTime());
            result.put("offlineMoney",offlineMoney.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString());
        }, executor);

        CompletableFuture<Void> refundMoneyFuture = CompletableFuture.runAsync(() -> {
            //退款金额
            BigDecimal refundMoney = crmInstrumentMapper.getRefundMoney(finalUserIdList, biParams.getStartTime(),biParams.getEndTime());
            result.put("refundMoney",refundMoney.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString());
        }, executor);

        CompletableFuture.allOf(contractMoneyFuture, orderMoneyFuture, receivablesMoneyFuture,firstReceivablesMoneyFuture,offlineMoneyFuture,refundMoneyFuture).exceptionally((e) -> {
            e.printStackTrace();
            return null;
        }).join();
        return result;
    }

    /**
     * 金额排行
     * @param biParams
     * @return
     */
    public List<JSONObject> rankStatis(BiParams biParams){
        if(!Optional.ofNullable(biParams.getStatisType()).isPresent()){
            biParams.setStatisType(CrmBusinessEnum.PublicEnum.ONE.getType());
        }
        if(!CrmBusinessEnum.PublicEnum.ONE.getType().equals(biParams.getStatisType())
                && !CrmBusinessEnum.PublicEnum.TWO.getType().equals(biParams.getStatisType())){
            biParams.setStatisType(CrmBusinessEnum.PublicEnum.ONE.getType());
        }
       List<Long> userIdList = buildUserList(biParams);
        log.info("金额排行  loginUser:"+UserUtil.getUser().getRealname()+",userIdList:"+JSONObject.toJSONString(userIdList));
        if(CollectionUtil.isEmpty(userIdList)){
            List<JSONObject> result = new ArrayList<>();
            return result;
        }
        List<JSONObject> result = new ArrayList<>();

        List<Long> finalUserIdList = userIdList;
        if(CONTRACT.getType().equals(biParams.getLabel())){
            result = crmInstrumentMapper.getContractRank(finalUserIdList, biParams.getStartTime(),biParams.getEndTime());
        }else if(RECEIVABLES.getType().equals(biParams.getLabel())){
            result = crmInstrumentMapper.getReceivablesRank(finalUserIdList, biParams.getStartTime(),biParams.getEndTime());
        }
        return result;
    }


    public List<Long> buildUserList(BiParams biParams){
        List<Long> selfAndChildUserIds = new ArrayList<>();
        if(!UserUtil.isAdmin()){
            BiParams queryParams = new BiParams();
            BeanUtil.copyProperties(biParams,queryParams);
            queryParams.setDeptIdArray(null);
            queryParams.setUserArray(null);
            queryParams.setDataType(DataTypeEnum.SELF_AND_CHILD.getType());
            BiAuthority biAuthority = handleDataType(queryParams);
            selfAndChildUserIds = biAuthority.getUserIds();

            List<Long> manageDeptUserIdList = SpringUtils.getBean(AdminService.class).queryUserIdsByManageDept();
            selfAndChildUserIds.addAll(manageDeptUserIdList);
        }else{
            selfAndChildUserIds.addAll(adminService.queryUserList());
        }

        List<Long> userIdList = new ArrayList<>();
        Integer[] deptIdArray = biParams.getDeptIdArray();
        if(Optional.ofNullable(deptIdArray).isPresent() && deptIdArray.length > 0){
            //当为部门选择器的时候
            List<Integer> deptlist = Arrays.asList(deptIdArray);
            userIdList.addAll(adminService.queryUserByDeptIds(deptlist));
        }
        Long[] userArray = biParams.getUserArray();
        if(Optional.ofNullable(userArray).isPresent() && userArray.length > 0){
            userIdList.addAll(Arrays.asList(userArray));
        }

        if(CollectionUtil.isNotEmpty(userIdList)){
            List<Long> finalSelfAndChildUserIds = selfAndChildUserIds;
            userIdList = userIdList.stream().filter(userId -> finalSelfAndChildUserIds.contains(userId)).collect(Collectors.toList());
        }else{
            userIdList.addAll(selfAndChildUserIds);
        }
        userIdList = userIdList.stream().distinct().collect(Collectors.toList());
        return userIdList;
    }

}
